文章目录
1. 面向对象特性之继承
extends
1.1 继承定义
就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性,相同的行为,子类可以直接询问父类中的非私有的属性和行为
格式:
class 子类 extends 父类{ ... };
好处
提高代码的复用性
类与类之间产生了关系,是多态的前提
继承和成员变量的特点
- 不重名;无影响
- 重名:子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用
super
关键字,修饰父类成员变量。Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能直接访问的。通常编码时,
我们遵循封装的原则
,使用private修饰成员变量,那么如何访问父类的私有成员变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。继承和成员方法的特点
- 不重名:如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
- 重名:如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
1.2 方法重写
子类中出现与父类
一模一样的方法时
(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。重载和重写:
- 重载:方法名相同,参数列表不同。
- 重写:方法名相同,参数列表相同。两个方法分布在子类和父类中。 又叫方法的覆盖、覆写。
重写的最主要的目的:对原有方法进行功能上的增强。
class Phone{ public void call(){ System.out.println("打电话"); } public void show(){ System.out.println("显示号码"); } } class Px extends Phone{ @Override public void show() { super.show(); System.out.println("显示来电号码的归属地"); } }
方法的重写的特别注意:
@override
检测当前注解下的(重写)方法是不是对父类方法进行了重写。- 访问权限:
public > protected >(default) > private
- 返回值类型
Object > String
- 父类中被重写的方法的访问权限 <= 子类的重写方法的访问权限。(正常开发的时候父子类的访问修饰符都是相同的。)
- 父类中被重写的方法的返回值类型要 >= 子类中被重写的方法的返回值类型。
@override
检测当前注解下的(重写)方法是不是对父类方法进行了重写。创建的是子类的对象,那么就优先使用的是子类的方法。所以重写才有意义。
1.4 继承格式
- 如果一个类没有使用extends 继承其他的类,那么默认继承的是Object. Object类是所有类的祖先。所有的类都继承了Object类。
- 子类继承了父类,那么子类就应该拥有了父亲的所有的属性和方法(局部变量,本类成员变量,父类的成员变量,继承的是父类成员属性和成员方法。)。
1.5 继承关系中-父子类构造方法的访问特点
子类的构造方法中有一个默认super()会调用,所以一定是先调用了父类的构造方法,然后才执行的子类的构造方法
子类的构造方法中可以通过 super( )来调用父类的构造方法。
super的在子类的构造器中的位置,必须是在第一语句上。而且子类的构造方法中只能有一个super调用。
总结:子类是必须调用父类构造方法。不写的话,默认添加一个super();写了的话,则调用指定的父类构造器。super只能有一个,而且必须是第一个语句。//正常来说 super只有在调用有参数的父类构造器的时候才会出现。
class Fu { int num = 10; public Fu(){ System.out.println("调用了父类的构造器,无can父类构造器"); } public Fu(int num) { System.out.println("调用了父类的构造器,有can父类构造器"); } } class Zi extends Fu{ int age = 10; String name ="taoge"; public Zi(){ // super(); super(10); //正常来说 super只有在调用有参数的父类构造器的时候才会出现。 // super();//子类构造器第一行默认有一个super调用了父类的构造器。 super可以不写,默认有, // 但是如果写了,只能放在第一行。 System.out.println("调用了子类的构造器"); } }
1.6 super和this
super:代表的是父类的存储空间(可以理解为父类的引用)
this:代表的是当前对象的引用
访问成员方法:
super.成员变量 父类的
this.成员变量 本类的
super.成员方法 父类的
this.成员方法 本类的
this();
//调用的本类的构造函数
super();
//调用的父类的构造函数。class Fu { int num = 5; } class Zi extends Fu { int num = 10; public void method() { int num = 30; //30 局部变量 System.out.println("num = " + num); //10 本类的成员变量 System.out.println("this.num = " + this.num); //5 父类的成员变量 System.out.println("super.num = " + super.num); } public void methods(){ // 有对象调用 this 如果在不产生变量冲突的情况下,this可以省略 //System.out.println("num = " + this.num);//10 //10 System.out.println("num = " + num); } }
子类的每个构造方法中均有默认的super()调用父类的空参构造。
手动调用父类构造会覆盖默认的super()。
super() 和this();都在构造方法的第一行所以不能同时存在。
只要创建子类的对象:父类的构造函数一定会被调用。
子类的构造函数也一样会被调用,所以我们说:
创建对象一定会调用构造函数
。
1.7 继承的特点
Java自支持单继承,不支持多继承
Java支持多层继承(继承体系),顶层父类是Object类所有的类默认继承Object,作为父类。
子类和父类是一种相对的概念
1.8 抽象类
- 父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。
- Java语法规定,包含抽象方法的类就是抽象类。
- 抽象类无法实例化对象:编译不通过。
- 父类要有无参构造方法,如果不加构造方法,会报错。
1.8.1 抽象方法
- 没有方法体的方法叫抽象方法。
- **
public abstract void eat();
**所以当前方法的方法体是没有任何作用的。- 抽象方法只有方法名,没有方法体。
- 非抽象方法,不需要重写,但是可以重写