【Java之轨迹】第三章:面向对象总结(类与对象、封装、继承)(上)

本文详细讲解了Java中的类与对象概念,包括类的抽象性和对象的内存分配;阐述了修饰符的作用,以及类、变量和构造器的使用规则。深入探讨了封装的实现方式、包的概念以及this关键字的用法。此外,还全面剖析了继承机制,包括单继承、方法重写、重写自检查和不可重写情况。构造器调用和this/super关键字在子类中的运用也做了实例演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


◉ 类与对象的概念

=> 类 :是一组相似事物的描述

  • 属于引用数据类型
  • 所以它和其他类型一样,是抽象的、不占用内存的。

=> 对象 :是类的具体表现

  • 属于数据
  • 所以它占据内存(且存放在堆内存中)

有static修饰的属于类,没有的属于对象


◉ 修饰符概念

private (私有的):只能在本类中访问
缺省 (友好的):能在同一个包下访问
protected (受保护的):能在同一个包下和子类访问
public (公开的):能在任何地方访问到


◉ 类(class、变量、构造器)

—— class
① 一个文件可以有多个 class ,但编译过后还是会生成多个.class文件
② 有且仅有 1 个被 public 修饰的 class,且名字应和文件名完全一致
③ 每个 class 都可以有一个 main 函数入口,在运行时可以选择使用哪一个入口(但不推荐)
④ 五大成分:成员变量,构造器,方法,内部类,代码块
⑤ 修饰符:缺省 | public ,abstract | final 可组合使用

—— 变量
详见:【Java之轨迹】第二章:局部变量、实例变量和类变量总结

—— 构造器
可使用的修饰符:public,private,protected,缺省
默认会有无参的构造器,但如果自己定义了构造器,该无参构造器会被覆盖


◉ 方法

① 分类

有 static 修饰的方法属于类,可以由类调用(类名.方法),也可以由对象调用。一般由类来调用。

没有 static 修饰的方法属于对象,只能由对象调用

② 方法重载

条件:在同一个类中,方法名相同,形参列表不同
(修饰符和返回值类型不起决定性作用)

③ 参数个数可变的方法

定义方法:(参数类型…参数名称)

注意点1: 可变参数可以看成一个数组

public static void test(int...num)
{
    for(int n: num) System.out.print(n + " ");
}

public static void main(String[] args)
{
    test(new int[]{2, 3, 4});
    test(5, 6, 78);
}
运行结果:2 3 4 5 6 7 8 

注意点2: 所以:可变参数和数组不能构成重载!
在这里插入图片描述

注意点3: 可变参数只能放在参数列表的最后一个(也说明了可变参数只能有一个)
在这里插入图片描述


◉ 封装

作用:使内部变量变得可控、安全

为了达到封装的目的
通常将成员变量设置为 private , 将方法设置为public
转而通过 set() get() 设置和访问成员变量的值

① 包

建包:在类的最上面加 package 包名
导包:在类的最上面加 import 包名.类名 / 包名.*

② this 关键字

this 代表的是对象(当前正在调用该方法的对象)
this(参数) 代表调用构造器

可以用在方法体(只能为实例方法)和构造器中

this代表的是当前正在调用该方法的对象,所以只能用于实例方法中而不能用于静态方法

举例:

public class Test1
{
    private int num;

    // 用在构造器中
    public Test1(int num)
    {
        this.num = num;
    }
    
    // 用在实例方法中
    public void setNum(int num)
    {
    	if(num > 0)
        	this.num = num;
        else
        	/* 提示错误... */
    }
    
    public int getNum()
    {
        return this.num;
    }
}

setNum() 中体现了封装使变量可控安全,可以通过内部处理筛选合理的赋值。

注意:this 一定一定不能出现在静态方法中,因为静态方法可以由类直接调用,这时候 this 指的是哪个对象就完全不知道了

this 在方法中也可以省略,默认会帮忙加上
但,前提是该方法体内没有同名的变量!!!

如上面的setNum() 中,方法体内已经由名字为num的变量,这时候当然不能写num=num;而应该使用 this 表明左值为该对象的成员变量
[ 就近原则,变量同名则优先选择距离近的而屏蔽远的 ]


◉ 继承

在类名之后使用 extends 进行继承
作用:提高代码复用

① 单继承

Java 只支持单继承,一个类只能有一个直接父类,可以有多个间接父类
如果没用extends继承,默认继承 Object (都是对象)

② 方法重写

发生在子父类之间
子类重写一个方法替代父类的方法
方法名和形参列表完全一致
子类的返回值类型需要和父类相同或者更小
子类的访问权限需要和父类相同或者更大

③ 重写自检查机制

推荐加 @Override ,为重写自检查
说明此方法必须是重写的方法(父类有此方法)
否则会报错(防止名字写错没有成功重写

④ 不可重写的情况

被 private 修饰的方法不能被重写,在子类中写完全一样的被认为是不同的方法而不是重写,如果加上@Override 就会报错 “方法不会实现或覆盖超类的方法”

public class Main extends Test2
{
	//@Override
    private int getInt()
    {
        return 10;
    }

    public static void main(String[] args)
    {
        Main main = new Main();
        System.out.println(main.getInt() );
    }
}

public class Test2
{
    private int getInt()
    {
        return 100;
    }
}
运行结果:10

看似好像 getInt 方法被重写了,但如果把注释去掉,加上了@Override
就可以看到提示:
在这里插入图片描述
说明检查结果是重写并没有成功。

静态方法也不能被重写,出现的情况和private的一样

⑤ 构造器调用

子类构造器总会在第一行调用父类构造器一次
如果没有显式地调用,就会默认地调用一次

注意:默认调用的只是无参构造器,如果自己写的父类中有有参构造器却没有自己写无参构造器,那么就不能依靠子类构造器去默认调用,会出错,必须自己显式调用然后传入参数。所以父类一般应手动加上一个无参构造器

public class Main extends Test2
{
    public Main()
    {
        System.out.println("子类Main无参构造器");
    }

    public static void main(String[] args)
    {
        Main main = new Main();
    }
}

public class Test2
{
    public Test2()
    {
        System.out.println("父类Test2无参构造器");
    }
}

运行结果:
在这里插入图片描述
但如果此时将父类 Test2 改为:

public class Test2
{
	/* [注释1]
    public Test2()
    {
        System.out.println("父类Test2无参构造器");
    }
    */
    
    public Test2(int i)
    {
        System.out.println("父类Test2有参构造器");
    }
}

那么会出现:
在这里插入图片描述
此时有两种方法:
第一种是显式地调用 super 如:
在这里插入图片描述

第二种是在父类手动添加无参构造器,如:将 [注释1] 去掉

⑥ this 和 super

this关键字
可以调用当前对象的构造器和方法以及变量

super关键字
可以调用当前对象的父类的构造器和方法及变量
如果方法已经被子类重写了,但子类依旧想调用父类的同名方法,可以使用super

this 和 super 后面直接加括号代表调用构造器
这时候只能放在方法的第一行而不能是其他位置
且这种方法只能在构造器体中调用而不能在其他方法体中
因此它们不能同时出现

利用上面 ⑤ 的例子,将 Main 的构造器改为:
在这里插入图片描述
那么将出现错误:
在这里插入图片描述
但如果是默认调用无参构造器 super() ,那么 superI() 和 this(1) 就可以同时起作用,如完整代码:

public class Main extends Test2
{
    public Main()
    {
        this(1);
        System.out.println("子类Main无参构造器");
    }

    public Main(int i)
    {
        System.out.println("子类Main有参构造器");
    }

    public static void main(String[] args)
    {
        Main main = new Main();
	}
}

public class Test2
{
    public Test2()
    {
        System.out.println("父类Test2无参构造器");
    }

    public Test2(int i)
    {
        System.out.println("父类Test2有参构造器");
    }
}

运行结果:
在这里插入图片描述


矢志不移,星辰为我而转(寒冰小澈)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒冰小澈IceClean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值