Java多态学习

一、多态的运行:
实例方法:动态绑定,即引用的变量实际引用的类型是哪一个,则运行哪一个实例方法。在运行时由java虚拟机动态决定。
静态方法:静态绑定,即引用的变量所声明的类型是哪一个,则运行哪一个静态方法。在编译阶段就已经做出了决定。
成员变量(包括静态变量和实例变量):静态绑定,即引用变量所声明的类型是哪一个,则运行哪个成员变量。在编译阶段就已经做出了决定。

public class Super {

    public String name = "父类名称";//实例变量

    public static String age = "父类年龄";//静态变量

    public void getName(){
        System.out.println("父类实例方法");
    }

    public static void getAge(){
        System.out.println("父类静态方法");
    }

}

public class Sub extends Super {

    public String name = "子类名称";//实例变量

    public static String age = "子类年龄";//静态变量


    public void getName(){
        System.out.println("子类实例方法");
    }

    public static void getAge(){
        System.out.println("子类静态方法");
    }

    public static void main(String[] args) {

        Super s = new Sub();
        System.out.println(s.name);//父类的名称
        System.out.println(s.age);//父类的年龄
        s.getName();//子类的实例方法
        s.getAge();//父类的静态方法


    }

}

Super s = new Sub();
引用变量所声明的类型 : Super
引用的变量实际引用的类型 :Sub

二、多态的分类

多态一般分为两种:重写式多态和重载式多态。重写和重载这两个知识点前面的文章已经详细将结果了,这里就不多说了。

重载式多态,也叫编译时多态。也就是说这种多态再编译时已经确定好了。重载大家都知道,方法名相同而参数列表不同的一组方法就是重载。在调用这种重载的方法时,通过传入不同的参数最后得到不同的结果。

重写式多态,也叫运行时多态。这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。
这种多态通过函数的重写以及向上转型来实现,我们上面代码中的例子就是一个完整的重写式多态。我们接下来讲的所有多态都是重写式多态,因为它才是面向对象编程中真正的多态。

二、父类类型的引用不能获取子类非继承的方法

三、当子类没有重写父类的方法,则会调用父类的方法

public class Super {


    public void getName(){
        System.out.println("父类实例方法");
    }

    public  void getAge(){
        System.out.println("父类静态方法");
    }

}

public class Sub extends Super {
    
    public  void getAge(){
        System.out.println("子类静态方法");
    }

    public static void main(String[] args) {

        Super s = new Sub();

        s.getName();//子类没有重写父类的方法getName(),所以调用的是父类的方法 父类的实例方法
        s.getAge();//子类的实例方法

    }
}

四、继承链中对象方法的调用的优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

}

class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    }
}

class C extends B{

}

class D extends B{

}

public class Demo {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));
    }
}
//结果:
//1--A and A
//2--A and A
//3--A and D
//4--B and A
//5--B and A
//6--A and D
//7--B and B
//8--B and B
//9--A and D

分析:4

首先,a2是类型为A的引用类型,它指向类型为B的对象。A确定可调用的方法:show(D obj)和show(A obj)。
a2.show(b) ==> this.show(b),这里this指的是B。 然后.在B类中找show(B
obj),找到了,可惜没用,因为show(B
obj)方法不在可调用范围内,this.show(O)失败,进入下一级别:super.show(O),super指的是A。 在A
中寻找show(B obj),失败,因为没用定义这个方法。进入第三级别:this.show((super)O),this指的是B。
在B中找show((A)O),找到了:show(A obj),选择调用该方法。 输出 B and A

参考博客: https://wj196.iteye.com/blog/1323244
https://blog.csdn.net/qq_38071429/article/details/85010402
http://blog.csdn.net/qq_31655965/article/details/54746235

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值