Java中的多态

声明:这片博客内容信息来源于书籍<Java编程思想>

Java编程语言有三个基本特征:

    1、封装:通过合并特征和行为来创建新的数据类型。

    2、继承:采用现有类的形式并在其中添加新代码,可以达到代码复用和使用原有类的属性和方法。

    今天的内容是讲多态

    所谓多态,就是同一种消息被多个对象接收而表现出不同的行为,前提这多个对象是同一个基类导出。

    看下面代码:

public class day01_2 {
    public static void main(String[] args) {
        Shape1 shape1 = new Circle1();
        shape1.draw();
        shape1.fun();
    }
}
class Shape1{
    public void draw(){
        System.out.println("Shape draw");
    }

    public static void fun(){
        System.out.println("Shape fun");
    }
}
class Circle1 extends Shape1{
    public void draw(){
        System.out.println("Circle draw");
    }

    public static void fun(){
        System.out.println("Circle fun");
    }
}

代码输出结果为


    首先我们来了解一下方法的绑定:

    将一个方法调用同一个方法主体关联起来被称为绑定,若在程序执行前进行绑定(也就是编译期绑定),叫做前期绑定

        例如上面的代码,sh有两个相同的方法draw,它怎么知道到底调用那个方法

    解决的方法就是动态绑定,就是在运行时根据对象的类型进行绑定。

    这样我们就能理解第一行的输出了,但是为什么第二行的输出是Shape fun呢

    这是因为在Java中,除了static和final方法(private方法属于final方法)之外,其他方法都是后期绑定。导致了输出为Shape fun。 

    多态也是有缺陷的:

    缺陷1:覆盖 私有方法

public class day01_3 {
    private void f() {
        System.out.println("private f");
    }

    public static void main(String[] args) {
        day01_3 day01_3 = new Derived();
        day01_3.f();
    }
}
class Derived extends day01_3{
    public void f(){
        System.out.println("public f");
    }
}

我们所希望的输出是public f,但由于private方法被自动认为是final方法,而且对导出类是屏蔽的。因此,在这种情况下,

Derived的f方法就是一个全新的方法,所以Derived的f方法并不是重载父类的f方法,输出就是public f

结论就是:只有非private方法才可以被覆盖,但还需要密切注意覆盖private方法的现象,虽然编译期不报错,但也不会按照

我么你的期望来执行。

缺陷2:域与静态方法:

一旦你了解多态机制,可能就会认为所有事物都可以多态发生。然而只有普通的方法调用可以是多态的。

例如你直接访问某个域或者静态方法。

public class day01_4 {
    public static void main(String[] args) {
        Super s = new Sub();
        System.out.println(s.f);
        s.printf();
    }
}
class Super{
    public int f = 0;
    public static void printf(){
        System.out.println("Super f");
    }
}
class Sub extends Super{
    public int f = 1;
    public static void printf(){
        System.out.println("Sub  f");
    }
}

它的输出全都是Super类的域和静态方法值,原因就是当Sub对象转型为Super,任何域访问操作都将由编译期解析,因此不是

多态的。

而静态方法是与类关联,而并非单个对象所关联。

希望大家能学习到知识,谢谢。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值