一、继承

1、继承的概念

对于某些类的一些共性我们避免重复编译,我们就可以将共性的内容进⾏抽取,从而达成代码的复用(静态变量、方法不被继承)

涉及  父类/基类/超类      子类/派生类

2、继承的语法

继承使用extends关键字==》扩展/拓展

3、父类成员变量、成语方法的访问

1)若该变量、方法只在父类中有,则子类对象.该成员变量即可访问父类

2)若该成员变量、方法在子类中重新定义,则优先访问子类

若子类重写了父类变量后,我们依然想在子类中访问父类变量就可以用super.该成员变量访问

4、super与this

super

1)在子类中通过或super调用父类成员变量、方法

2)子类构造方法中必须通过super调用父类的构造方法

1>若父类中没有写构造方法或只有无参构造方法,子类默认调用父类无参构造方法,及编译器自动生成:

public Cat(){

super();

}

2>若父类中有有参构造方法,则在子类中必须定义构造方法,且在第一行使用super调用父类的构造方法

3>若父类中含有多个构造方法,则在子类构造方法中中必须通过super参数确定调用哪一个,且this与super不能同时出现

5、继承中代码块的执行顺序

                 

   

我们可以看到顺序为:父类静态代码块==》子类静态代码块==》父类非静态代码块==》父类构造方法==》子类非静态代码块==》子类构造方法(且静态代码块只执行一次)  

6、继承中的权限控制符

主要介绍protected

同包下不同类可以调用protected修饰的变量

不同包下子类可以调用父类protected修饰的变量

不同包下,C继承Base,B也继承Base,但在B类中不能通过创建C的对象来调用a

不同包的子类中不能通过创建父类对象来调用父类变量,但能通过super调用

7、final关键字

1)final修饰类表示类不能被继承

2)final修饰变量表示变量不能被再次赋值

3)final修饰方法则表示方法不能被重写

二、多态

1、向上转型

1>

public class Test {
    static void main(String[] args) {
        Animal animal=new Cat("xiaomimi",12.5,"yellow");
    }

父类的引用变量可以接受子类对象,父类相当于一个更大范围的变量,相当于double与int

作为参数传递,输出

这是发生了动态绑定,即在编译阶段编译器认为调用的Animal的eat()方法,但在运行阶段调用各自子类的eat()方法

静态绑定:编译期间确定调用哪一个方法

作为方法返回值类型

2>向下转型

Animal a1=new Dog();此时我们用a1.eat();调用的是父类的eat()方法,a1.bark()会报错

Dog dog=(Dog)a1;(不加会报错)

因为此时a1相当于一个范围更大的类型,用小类型接受大类型必须强转

强传后a1.eat()调用的就是Dog的eat方法,a1.bark()也不会报错

而Cat cat=(Cat)a1;

在调用a1.bark()汇报类型转换错误

所以在将父类引用赋值给子类再调用时,要引入一个判断操作,instanceof关键字

Animal animal=new Dog();

if(animal instanceof Dog){

Dog dog=(Dog)animal;

dog.bark();

}else{

Cat cat=(Cat)animal;

cat.mew();

}

2、重写

@Override

表示当前方法被重写,若父类中没有该方法或与父类方法格式不一样,则报错

重写的规则

1、方法名、返回值、参数列表都一样

2、对于方法的访问修饰符,子类权限一定要大于父类权限(public>protected>默认>private)

3、对于父类private修饰的方法,子类没法重写

4、对于父类static修饰的方法,子类没法重写

5、被final修饰的方法,子类不能重写

6、构造方法不能被重写

重载(overload)

方法名相同、参数列表不同、返回值不要求

三、继承和多态的应用

1、画图形

定义三个图形,对draw()方法进行重写

传统方法,圈复杂度太大

利用多态,调用时发生动态绑定

2、

class B {
public B() {
   func();
}
public void func() {
System.out.println("B.func()");
   }
}
class D extends B {
private int num = 1;
@Override
public void func() {
    System.out.println("D.func() " + num);
   }
}
public class Test {
public static void main(String[] args) {
    D d = new D();
  }
}
调用父类的构造方法,调用func(),func()被重写所以调用子类func()输出D.func()此时还没有被赋值默认值是0;所以输出:D.func()0

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐