Java继承和多态还不了解吗?【详细示例解析】

1.继承

Bird类继承Animal类
由于Animal类有构造方法,因此Bird类内部也需要用super构建一个构造方法

package com.bit.demo1;

class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
        System.out.println(this.name + "Animal构造方法");
    }

    public void eat(String food) {
        System.out.println(this.name + "正在吃" + food);
    }
}

/**
 * 子类 extends 父类
 * 子类:派生类
 * 父类:基类,超类
 * 1.Java 中使用extends只能单继承[继承一个类]
 * 2.对于父类中的private方法或属性,子类无法访问
 * 3.子类在构造的时候,要先帮助父类构造
 * <p>
 * this()-->调用本类其它的构造方法
 * this.data-->访问当前类当中的属性
 * this.func()-->调用本类的其它成员方法
 * <p>
 * super()-->调用父类的构造方法
 * super.data-->访问父类的属性
 * super.func()-->访问父类的成员方法
 * <p>
 * <p>
 * 切忌继承超过3层
 * 如果不想让此方法被继承,可用final修饰
 * final int a = 0-->常量,只能被初始化一次,接下来就不能再来修改
 * final 修饰类: 密封类 特性:不能被继承。一旦一个类被final修饰,那么这个类必然不能被继承
 * final 修饰方法:
 */
//class Cat extends Animal {
//    public Cat(String name) {
//        super(name);//显式调用
//        super.name = "qiqi";
//        System.out.println(this.name + "Cat(String)");
//    }
//    /*public String name;
//
//    public void eat() {
//        System.out.println(this.name + "Cat::eat()");
//    }*/
//}

class Bird extends Animal {
    public String name;

    public Bird(String name) {
        super(name);
        System.out.println(super.name);
    }

    public void fly() {
        System.out.println(super.name + "正在飞");
    }
}

final class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Bird bird = new Bird("小鸟");
        System.out.println(bird.name);
        bird.fly();
    }
}

2.public,protected,default,private的继承关系

No范围privatedefaultprotectedpublic
1同一包中的同一类
2同一包中的不同类
3不同包中的子类
4不同包中的非子类

我们希望类要尽量做到 “封装”, 即隐藏内部实现细节, 只暴露出 必要 的信息给类的调用者.
因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限. 例如如果一个方法能用 private,
就尽量不要用 public.
另外, 还有一种 简单粗暴 的做法: 将所有的字段设为 private, 将所有的方法设为 public. 不过这种
方式属于是对访问权限的滥用, 还是更希望同学们能写代码的时候认真思考, 该类提供的字段方法
到底给 “谁” 使用(是类内部自己用, 还是类的调用者使用, 还是子类使用)

3.向上转型

package com.bit.demo2;

class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal(String)");
    }
    public void eat() {
        System.out.println(this.name + "Animal::eat()");
    }
}

class Cat extends Animal {
    public int count =99;
    public Cat(String name) {
        super(name);
        System.out.println("Cat(String)");
    }
}

class Bird extends Animal {
    public String name;

    public Bird(String name) {
        super(name);
        System.out.println(super.name);
    }
    public void fly() {
        System.out.println(super.name + "Bird::fly()");
    }
}

public class TestMain {

    public static Animal func() {
        Cat cat = new Cat("咪咪");
        return cat;
    }
    public static void main(String[] args) {
        Animal animal = func();
        animal.eat();
    }
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main3(String[] args) {
        Cat cat = new Cat("咪咪");
        func(cat);
    }
    //向上转型
    public static void main2(String[] args) {
        /*
        向上转型: 父类引用 引用子类对象
         */
        Animal animal = new Cat("咪咪");
        animal.eat();
    }
    public static void main1(String[] args) {
        Animal animal = new Animal("豆豆");
        Cat cat = new Cat("咪咪");
//        animal.count;//error: 向上转型之后,通过父类的引用 只能访问父类自己的方法或者属性。父类引用只能访问自己的
    }
}

4.区分重写和重载

package com.bit.demo3;

class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal(String)");
    }

    public void eat() {
        System.out.println(this.name + "Animal::eat()");
    }
}

class Cat extends Animal {
    public int count = 99;

    public Cat(String name) {
        super(name);
        System.out.println("Cat(String)");
    }

    public void eat() {
        /*
         重载: overload
        方法名相同
        参数列表不同(参数的个数+类型)
        返回值不做要求
        同一个类中

        重写: override
        方法名相同
        返回值相同
        参数列表相同
        不同的类-->继承关系上

        注意事项:
        1.需要重写的方法不能是被final修饰的。被final修饰之后,他是密封方法,不可以修改
        2.被重写的方法,访问修饰限定符一定不能是私有的
        3.被重写的方法,子类当中的访问修饰限定夫要大于等与父类的修饰访问限定符【private < default < protected < public
        4.static修饰的方法不能被重写
         */
        System.out.println(this.name + "重写Cat::eat()");
    }
}

class Bird extends Animal {
    public String name;

    public Bird(String name) {
        super(name);
        System.out.println(super.name);
    }

    public void fly() {
        System.out.println(super.name + "Bird::fly()");
    }
}

public class TestMain {
    /*
    多态
    运行时绑定【动态绑定】
    父类引用 引用子类对象,同时 通过父类引用调用同名的覆盖方法
    此时就会发生运行时绑定

    反编译Java代码
    D:\Progam\jetBrains\IDEA\高博\src\com\bit\demo3>javac -encoding utf8 TestMain.java
    D:\Progam\jetBrains\IDEA\高博\src\com\bit\demo3>javap -c TestMain
    警告: 二进制文件TestMain包含com.bit.demo3.TestMain
    Compiled from "TestMain.java"
    public class com.bit.demo3.TestMain {
      public com.bit.demo3.TestMain();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return

      public static void main(java.lang.String[]);
        Code:
           0: new           #2                  // class com/bit/demo3/Cat
           3: dup
           4: ldc           #3                  // String 咪咪
           6: invokespecial #4                  // Method com/bit/demo3/Cat."<init>":(Ljava/lang/String;)V
           9: astore_1
          10: aload_1
          11: invokevirtual #5                  // Method com/bit/demo3/Animal.eat:()V
          14: return
    }


     1: invokespecial #1                  // Method java/lang/Object."<init>":()V 【运行--》这里代表调用了构造方法】
     11: invokevirtual #5                  // Method com/bit/demo3/Animal.eat:()V 【编译--》代表调用方法了。非静态方法】
     */
    public static void main(String[] args) {
        Animal animal = new Cat("咪咪");
        animal.eat();
    }
}

5.向下转型,动态绑定那些坑

package com.bit.demo4;

class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal(String)");
        eat();
    }

    public void eat() {
        System.out.println(this.name + "Animal::eat()");
    }
}

class Cat extends Animal {
    public int count = 99;

    public Cat(String name) {
        super(name);
        System.out.println("Cat(String)");
    }

    public void eat() {
        System.out.println(this.name + "重写Cat::eat()");
    }
}

class Bird extends Animal {
    public String name;

    public Bird(String name) {
        super(name);
    }

    public void fly() {
        System.out.println(super.name + "Bird::fly()");
    }
}

public class TestMain {
    /*
    一个坑:类的在构造方法中调用时可以发生运行时绑定
     */
    public static void main(String[] args) {
        Cat cat = new Cat("嘻嘻");
//        cat.eat();
    }

    // 不安全的向下转型: 猫不能bird化
    public static void main2(String[] args) {
        Animal animal = new Cat("咪咪");
        /*Bird cat = (Bird) animal;
        cat.fly();*/

        /*
         instance解决
         A instance B
         判断A 是不是 B的一个类
         */
        if (animal instanceof Bird) {
            Bird cat = (Bird) animal;
            cat.fly();
        } else {
            System.out.println("向下转型之间不是同一个类");
        }
    }

    public static void main1(String[] args) {
        /*
        向下转型
        注意:非常不安全,很少使用
         */
        Animal animal = new Bird("八哥");
        animal.eat();

        // 向下转型-->父类的引用赋值给了子类
        Bird bird = (Bird) animal;
        bird.fly();
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值