java学习(十)继承extends、方法覆盖、多态

java学习(十)继承extends、方法覆盖、多态

继承语法

class 类名 extends 父类名{

​ 类体;

}

  • java中规定,子类继承父类,除构造方法不能继承之外,剩下的都可以继承。但是private修饰的私有属性无法在子类中直接访问。

     

方法覆盖:重写父类方法

  • 中国人和美国人都继承人类,中国人调用打招呼希望输出“你好”,但是美国人调用打招呼希望输出“hi,hello”,这时候人类的到招呼方法就不满足需要了,需要方法覆盖。其实就是重写了父类方法。

代码:

public class People{
    private String name;
​
​
    public String getName(){
        return name;
    }
​
    public void setName(String name){
        this.name = name;
    }
    
    //定义一个方法
    public void speakHi(){
        System.out.println(this.name + "打个招呼");
    }
​
}
public class ChinesePeople extends People{
    
    public void speakHi(){
    
        System.out.println("你好,我是 " + this.getName() + ",认识你很高兴");
​
    }
}
public class AmericaPeople extends People{
    
    public void speakHi(){
    
        System.out.println("Hi,My name is:" + this.getName() + ",nice to meet you");
​
    }
}
public class PeopleTest {
    public static void main(String[] args) {
        ChinesePeople cp = new ChinesePeople();
        cp.setName("法外狂徒张三");
        cp.speakHi();
​
        AmericaPeople ap = new AmericaPeople();
        ap.setName("tony");
        ap.speakHi();
    }
}

 

多态:其实就是同一个行为发生在不同的对象上会有不同的效果。

看Test01和Test02代码

public class  Animal{
    public  void move(){
        System.out.println("动物会移动");
    }   
}
public class Cat extends Animal{
​
    //方法覆盖
    public void move(){
        System.out.println("猫会跑的!");
    }
​
    //猫特有方法
​
    public void catchMouse(){
​
        System.out.println("猫可抓老鼠!");
​
    }
}
public class Bird extends Animal{
    
    
    //方法覆盖
    public void move(){
​
        System.out.println("鸟会动的!");
    }
    
    //鸟特有的方法
    public void fly(){
        
        System.out.println("鸟飞了飞了!");
    }
}

Test01.java:

public class Test01 {
    public static void main(String[] args) {
        //创建 Animal 对象
        Animal a = new Animal();
        a.move();
        //创建 Cat 对象
        Cat c = new Cat();
        c.move();
        c.catchMouse();
        //创建鸟儿对象
        Bird b = new Bird();
        b.move();
        b.fly();
    }
}

Test02.java:

public class Test02{
    public static void main(String[] args) 
    {
        //向上转型
        Animal a1 = new Cat();
        a1.move();
        
        //向上转型
        Animal a2 = new Bird();
        a2.move();
    }
}

​ 解释:在编译阶段编译 器只知道 a1 变量的数据类型是 Animal,那么此时编译器会去 Animal.class字节码中查找 move() 方法,发现 Animal.class 字节码中存在 move()方法,然后将该 move()方法绑定到 a1 引用上, 编译通过了,这个过程我们可以理解为“静态绑定”阶段完成了。紧接着程序开始运行,进入 运行阶段,在运行的时候实际上在堆内存中 new的对象是 Cat 类型,也就是说真正在 move 移 动的时候,是 Cat 猫对象在移动,所以运行的时候就会自动执行 Cat 类当中的 move()方法,这 个过程可以称为“动态绑定”。但无论是什么时候,必须先“静态绑定”成功之后才能进入“动 态绑定”阶段。

向上转型:自动类型转换

  • java 中之所以有多态机制,是因为 java 允许一个父类型的引用指向一个子类型的对象。 这种父类型引用指向了子类对象属于向上转型,或者叫自动类型转换

向下转型:强制类型转换

  • 如果想调用子类特有方法,就需要向下转型

public class Test04 {
    public static void main(String[] args) {
        //向上转型
        Animal a = new Cat();
        
        //a.catchMouse();  //编译报错
        
        //向下转型:为了调用子类对象特有的方法
        //强制类型转换将 Animal 类型的 a 引用转换成 Cat 类型的引用c
        Cat c = (Cat)a;
        c.catchMouse();
    }
}

上面代码a.catchMouse();为什么报错呢?

​ 那是因为“Animal a = new Cat();”在编译的时候,编译器只知道 a 变量的数据类型是 Animal,也就是说它只会去 Animal.class 字节码中查找 catchMouse()方法,结果没找到,自然“静态绑定”就失败了,编 译没有通过。就像以上描述的错误信息一样:在类型为 Animal 的变量 a 中找不到方法 catchMouse()。

类型转换异常

public class Test05 {
    public static void main(String[] args) {
        Animal a = new Bird();
        Cat c = (Cat)a;
    }
}

上述代码可以编译通过,原因是编译器只知道 a 变量是 Animal 类型,Animal 类和 Cat 类之间存在继承关系 ,所以可以进行向下转型 ,语法没问题,问题是运行的时候a引用指向实际是鸟啊,你强制转猫,就报错了。

运算符 instanceof:结果是布尔值,如果是true就可以转型,false就不可以转型。

instanceof 运算符 语法格式:

(引用 instanceof 类型)

代码:

public class Test05 {
    public static void main(String[] args) {
​
​
        Animal a = new Bird();
​
        if (a instanceof Cat){  //判断引用a是不是Cat类型
​
            Cat c = (Cat)a;
            c.catchMouse();
​
        }else if(a instanceof Bird){  //判断引用a是不是Bird类型
​
        
            Bird b = (Bird)a;
            b.fly();
        
        }
       
    }
}

其实多态存在的三个必要条件分别是:

① 继承

② 方法覆盖

③ 父类型引用指向子类型对象 ,子类将方法重写之后调用到子类对象上的 方法产生不同效果时,多态就形成了。

静态方法的“覆盖”是没有意义的,所以通常我们不谈静态方法的覆盖。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值