Java面向对象部分重点笔记
类的定义
在类中,属性是通过成员变量体现的,而行为是成员函数(又称为方法)实现的,下面为大家演示Java中定义类的通用格式,其语法格式如下:
对象的创建与使用
类是对象的抽象,为对象定义了属性和行为,但类本身既不带任何数据,也不存在于内存空间中。而对象是类的一个具体存在,既拥有独立的内存空间,也存在独特的属性和行为,属性还可以随着自身的行为而发生改变。接下来演示如何用类创建对象,创建对象之前,必须先声明对象,其语法格式如下:
类是自定义类型,也是一种引用类型,因此该对象名是一个引用变量,默认值为null,表示不指向任何堆内存空间。接下来需要对该变量进行初始化,Java使用new关键字来创建对象,也称实例化对象,其语法格式如下:
声明和实例化对象的过程可以简化,其语法格式如下:
演示创建Person类的实例对象,具体示例如下:
示例中,“Person p”声明了一个Person类型的引用变量,“new Person()”为对象在堆中分配内存空间,最终返回对象的引用并赋值给变量p,如图所示。
对象实例化后,就可以访问对象的成员变量和成员方法,其语法格式如下:
从运行结果可发现,变量p1、p2引用的对象同时调用了say()方法,但输出结果却不相同。这是因为用new创建对象时,会为每个对象开辟独立的堆内存空间,用于保存对象成员变量的值。因此,对变量p1引用的对象属性赋值并不会影响变量p2引用对象属性的值。变量p1、p2引用对象的内存状态如图所示。
示例中,第16行代码p2被赋值为p1后,会断开原有引用的对象,而和p1引用同一对象。此时,p2原有引用的对象不再被任何变量所引用,就成了垃圾对象,不能再被使用,只等待垃圾回收机制进行回收。垃圾产生的过程如图所示。
继承
在Java中,子类继承父类的语法格式如下:
Java使用extends关键字指明两个类之间的继承关系。子类继承了父类中的属性和方法,也可以添加新的属性和方法。
Java语言只支持单继承,不允许多重继承,即一个子类只能继承一个父类,否则会引起编译错误,具体示例如下:
Java语言虽然不支持多重继承,但它支持多层继承,即一个类的父类可以继承另外的父类。因此,Java类可以有无限多个间接父类,具体示例如下:
重写父类方法
在继承关系中,子类从父类中继承了可访问的方法,但有时从父类继承下来的方法不能完全满足子类需要,例如上例中,如果要求父类与子类中的say()方法输出不同内容,这时就需要在子类的方法里修改父类的方法,即子类重新定义从父类中继承的成员方法,这个过程称为方法重写或覆盖。在进行方法重写时必须考虑权限,即被子类重写的方法不能拥有比父类方法更加严格的访问权限,如例所示。
重写 总结
重写:需要有继承关系,子类重写父类的方法!
-
方法名必须相同
-
参数列表必须相同
-
修饰符:范围可以扩大 : public > Protected > Default > private
-
抛出的异常:范围,可以被缩小,但不能扩大; ClassNotFoundException (范围小) --> Exception (范围大)
重写,子类的方法和父类必须要一致:方法体不同!
为什么需要重写
-
父类的功能,子类不一定需要,或者不一定满足!
插入重写快捷键:Alt + Insert ; 选中 override;
super关键字
当子类重写父类方法后,子类对象将无法访问父类被重写的方法。如果在子类中需要访问父类的被重写方法,可以通过super关键字来实现,其语法格式如下:
在继承中,实例化子类对象时,首先会调用父类的构造方法,再调用子类的构造方法,这与实际生活中先有父母再有孩子类似。子类继承父类时,并没有继承父类的构造方法,但子类构造方法可以调用父类的构造方法。在一个构造方法中调用另一个重载的构造方法使用this关键字,在子类构造方法中调用父类的构造方法时应使用super关键字,其语法格式如下:
另外,子类中如果没有显式地调用父类的构造方法,将自动调用父类中不带参数的构造方法。
super注意点
-
super调用父类的构造方法,必须在构造方法的第一个
-
super 必须只能出现在子类的方法或者构造方法中!
-
super 和 this不能同时调用构造方法!
对比 this:
-
代表的对象不同:
this:代表本身调用的当前对象
super:代表被调用的父类对象的引用
-
前提:
this:没有继承也可以使用
super:只能在继承条件下才可以使用
-
构造方法:
this() ; 本类的构造
super() ; 父类的构造
final关键字
final关键字修饰类
在Java中,为了考虑安全因素,要求某些类不允许被继承或不允许被子类修改,这时可以用final关键字修饰。它可用于修饰类、方法和变量,表示“最终”的意思,即用它修饰的类、方法和变量不可改变,具体特点如下:
final修饰的类不能被继承
final修饰的方法不能被子类重写。
final修饰的变量是常量,初始化后不能再修改。
使用final关键字修饰的类称为最终类,表示不能再被其他的类继承,如Java中的String类。接下来演示final修饰类,如例所示。
例中,使用final关键字修饰了Parent类。因此,Child类继承Parent类时,程序编译结果报错并提示“无法从最终Parent进行继承”。由此可见,被final修饰的类为最终类,不能再被继承。
final关键字修饰方法
使用final关键字修饰的方法,称为最终方法,表示子类不能重写此方法,接下来演示final修饰方法,如例所示。
例中,Parent类中使用final关键字修饰了成员方法say(),Child类继承Parent类并重写了say()方法。程序编译结果报错并提示“被覆盖的方法为final”。由此可见,被final修饰的成员方法为最终方法,不能再被子类重写。
final关键字修饰变量
使用final关键字修饰的变量,称为常量,只能被赋值一次。如果再次对该变量进行赋值,则程序在编译时会报错,如例所示。
上例中,使用final修饰变量PI,再次对其进行赋值,程序编译结果报错并提示“无法为最终变量PI分配值”。由此可见,final修饰的变量为常量,只能初始化一次,初始化后不能再修改。
上例中,使用final修饰的是局部变量,接下来使用final修饰成员变量,如下例所示。
例中,在Parent类中使用final修饰了成员变量PI,程序编译结果报错并提示“可能尚未初始化变量PI”。由此可见,Java虚拟机不会为final修饰的变量默认初始化。因此,使用final修饰成员变量时,需要在声明时立即初始化,或者在构造方法中进行初始化。
下面使用构造方法初始化final修饰的成员变量,在Parent类中添加代码具体如下:
此外,final关键字还可以修饰引用变量,表示该变量只能始终引用一个对象,但可以改变对象的内容,有兴趣的读者可以动手验证一下。
多态
-
实现动态编译 ; 提高程序可扩展性
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
一个对象的实际类型时确定的,但可以指向对象的引用类型有很多
多态存在的条件:
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
多态部分注意事项
-
多态是方法的多态,属性没有多态性
-
需要父类和子类之间有联系,不然容易出现类型转换异常(ClassCastException)!
-
存在条件:
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
-
-