多态特性

面向对象的三大特性:封装,继承,多态,其中封装和继承是多态的基础

概述:某一个事物,在不同时刻表现出来的不同状态,父类的声明指向子类的实现,父类可以调用子类重写后的方法。

转型操作:
向上转型:父类的声明指向子类的实现

向下转型: 假如子类声明指向父类实现,这是非法的。如果将父类型声明数据赋值给子类型,不管父类真实类型是什么,都是非法的。那么应该怎么办呢?可以使用强转语法。子类类型声明 对象名 = (子类类型)父类型变量

Pet p = new Cat();
Cat cat = (Cat)p;

但是强转语法有安全隐患,因为你不能把Pet(宠物)中的Cat(猫)赋值给Dog(狗)吧,所以应该加上判断条件。

Pet p = new Cat();
if(p instanceof Dog){
Dog dog = (Dog)p;
}

多态的三个前提
继承或者实现
子类重写父类中的方法
父类的引用指向子类的对象

注意面试:
静态字段操作 —— 调用的父类的
静态方法操作 —— 调用的父类的
成员字段操作 —— 调用的父类的

package Test02;

public class Fu {
    static int age=50;
    int salary=30000;
    public void show(){
        System.out.println("fulei!");
    }
    public static void eat()
    {
        System.out.println("fulei");
    }

}
package Test02;

public class Zi extends Fu {
    static int age=20;
    int salary=15000;
    public void show(){
        System.out.println("子类");
    }
    public static void eat(){
        System.out.println("子类");
    }

}
package Test02;

public class Demo01 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Fu a=new Zi();
        a.show();//非静态成员方法,子类
        a.eat();//静态成员方法,父类
        System.out.println(a.age);//静态字段,父类
        System.out.println(a.salary);//成员字段,父类
    }
}

结果:
子类
fulei
50
30000
记住:
多 态:编译看左(父类),运行看右(子类)
非多态:编译看左,运行看左。非多态特指父类声明指向子类实现,调用成员字段或静态字段或静态方法
比如对于a.show(),假如Fu类中没有show方法,则编译不能通过,若Fu类中有show方法,则调用的是Zi的方法。

下面是一个面试题,请问输出什么?

package Test03;
public class Base {
    private String baseName="base";
    public Base(){
        callName();
    }
    public void callName(){
        System.out.println(baseName);
    }
    static class Sub extends Base{
        private String baseName="sub";
        public void callName(){
            System.out.println(baseName);
        }
    }
    public static void main(String[] args) {
        Base b=new Sub();
    }
}

结果为null,因为在new Sub()时,会调用父类中的构造方法Base(),从而会调用callName()方法,由于子类中有callName(),所以此时调用的是子类中的clllName()方法,而此时子类还没有构造,所以baseName的值为null;

package Test03;

public class Base {
    private String baseName = "base";

    public Base() {
        callName();
    }

    public void callName() {
        System.out.println(baseName);
    }

    static class Sub extends Base {
        private String baseName = "sub";

//      public void callName() {
//          System.out.println(baseName);
//      }
    }

    public static void main(String[] args) {
        Base b = new Sub();
    }
}

这时结果为base,因为此时子类中没有callName()方法,所以调用的是父类中的callName()方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值