java--10--多态

参考大神博客:
http://www.cnblogs.com/chenssy/p/3372798.html
1 多态,编译时的类型和运行时的类型不一致,当运行时调用该引用变量的方法时,其总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现,相同类型的变量,调用其中的方法时呈现出多种不同的行为特征。
例:

class BaseClass{
    public int book=6;

    public void base(){
        System.out.println("BaseClass:base");
    }

    public void test(){
        System.out.println("BaseClass:test()");
    }
}

class SubClass extends BaseClass{

    //重新定义一个变量
    public String book="子类中定义的变量";

    //子类覆盖父类的方法
    public void test(){
        System.out.println("SubClass:text()");
    }

    //子类中定义的普通方法
    public void sub(){
        System.out.println("SubClass:sub");
    }
}

public class TextDemo_14 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BaseClass text=new SubClass();
        System.out.println(text.book);//重写父类的变量,还是返回的是父类中的变量
        text.base();//子类无重写该方法,执行的是父类中base方法
        text.test();//重写父类的方法,执行的是子类的test方法,即重写后的方法
        //text.sub();指向父类的变量无法访问子类的中的方法,打开编译时显示错误
    }
}

2 多态:
在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。
比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:
酒 a = 剑南春
酒 b = 五粮液
酒 c = 酒鬼酒

这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。
向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们。所以父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在与子类中的方法和属性它就望尘莫及了
总结:
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

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 TextDemo_14 {
    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("4--" + a2.show(b));// B and A
        // 推理过程----》
        // 先在父类A中看找到该方法,因为C类继承自A和B,在A中有一个方法中的参数即是C类的父类可以匹配到,
        // 看在B类中重写了该方法,即执行该方法
        System.out.println("5--" + a2.show(c));// B and A
        System.out.println("6--" + a2.show(d));// A and D
        System.out.println("7--" + b.show(b));// B and B
        System.out.println("8--" + b.show(c));// B and B
        System.out.println("9--" + b.show(d));// A and D
    }
}

总结:
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
未完待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值