面向对象——继承和多态

面向对象——继承和多态

一. 继承

1.继承:

是一种机制,可以进行代码的重用——基类(超类) 子类(派生类)   子类继承了 父类的除构造函数外的所有属性

2.super关键字:

  • super():----->调用基类的构造函数 //必须放在第一行
  • super.data------->访问基类的数据成员
  • super.func();—>调用基类的成员方法
class Base{
    protected int a;
    public Base (int a){
        fun1();
        this.a=a;
    }
    public void fun1() {
        System.out.println("Base.fun1()"+ this.a);
    }
}
class Childern extends Base{
    private int b;
    public Childern(int a,int b) {
        super(a);
        super.a = 10;
        super.fun1();
        a=10;
        this.b=b;
        System.out.println("Childern.init()...");
    }
    public void fun1() {
        System.out.println("Childern.fun1()");
    }

    public void fun1(int a) {
        System.out.println("Childern.fun1(int)");
    }
}

3.派生类构造对象的初始化顺序

class Base{
    protected int a;
    public Base (int a){
        fun1();
        System.out.println("Base.init()...");
        this.a=a;
    }
    static {
        System.out.println("Base.static...");
    }
    {
        System.out.println("Base.instance...");
    }
    public void fun1(){
        System.out.println("Base.fun1()..."+this.a);
    }
    public static void fun2(){
        System.out.println("Base.fun2()...");
    }
}
class Childern extends Base{
    private int b;

    public Childern(int a,int b) {
        super(a);
        a=10;
        this.b=b;
        System.out.println("Childern.init()...");
    }
    static {
        System.out.println("Childern.static...");
    }
    {
        System.out.println("Childern.instance...");
    }
    public void fun1(){
        System.out.println("Childern.fun1()...");
    }
    public void fun1(int a){
        System.out.println("Childern.fun1(int)...");
    }
    public static void fun2(){
        System.out.println("Childern.fun2()...");
    }
}

public class Test1031_2 {
    public static void main(String[] args) {
        Base base =new Childern(1,2);
    }

打印结果为:

Base.static...
Childern.static...
Base.instance...
Childern.fun1()...
Base.init()...
Childern.instance...
Childern.init()...

可以看出派生类构造对象的初始化顺序:

  1. 基类的静态块初始化,
  2. 派生类的静态块初始化
  3. 基类的实例块初始化
  4. 基类的构造函数
  5. 派生类的实例块初始化
  6. 派生类的构造函数

4.基类的数据成员在派生类当中的访问权限

同包子类 同包非子类 不同包子类 不同包非子类
public 可以 可以 可以 可以
private 不可以 不可以 不可以 不可以
protected 可以 可以 不可以 不可以
默认权限 可以 可以 不可以 不可以

5.基类和派生类之间的相互赋值

派生类的值可以赋值给基类;

但是基类的值不能赋值给派生类

例如:上面那段代码 然后主函数改成:

public static void main1(String[] args) {
        Base base = new Base(1);

        Childern childern = new Childern(1,2);
        base = childern;//这句就是正确的
        childern = base;//这句就是错误的,error
    }

6.重载overlode; 函数名相同,参数列表不相同,与函数返回值无关  并不一定在同一个类当中;继承关系上也可以构成重载;

重写/覆盖overwrite;函数名相同,参数列表相同,函数返回值相同

三.多态:

基类引用了派生类对象,并且基类和派生类有同名的覆盖方法

动多态:发生在运行的时候

静多态:发生在编译的时候

方法表是在编译的时候生成的,

一般的对象放在堆里 class对象例外放在方法区

方法表和类型一一对应

public static void main2(String[] args) {
        Base base=new Base(1);
        Childern childern=new Childern(1,2);
        base=childern;
    }

    public static void main3(String[] args) {
        Base base=new Base(1);
        base.fun1();
        System.out.println("===============");
        Childern childern=new Childern(1,2);
        childern.fun1();
    }

    public static void main4(String[] args) {
        Base base=new Childern(1,2);
        base.fun1();//动多态  运行的时候
        Base.fun2();//静多态  编译的时候

猜你喜欢

转载自blog.csdn.net/qq_39602004/article/details/83587480