08_多态

1.多态

1.1多态

1.1.1多态的概念

:同一对象

不同:条件不同

:对同一行为

不同:实现的结果不同

程序中:同一引用类型,由于实例不同,对同一方法产生的结果不同

1.1.2多态的实现

package com.chenlan03.poly1;

public class Test {
    public static void main(String[] args) {
        Pet pet = null;
        pet = new Dog("lala", 90, 90, "拉布拉多犬");
        pet.showInfo();
        pet = new Penguin("heha", 80, 80, "Q仔");
        pet.showInfo();
    }
}

20200903133840370

[1] 多态一定建立在继承的基础上

[2] 多态形式上表现为 父类对象调用子类实例

[3] 当父类引用子类时,通过父类调用方法一定是子类重写、实现的方法

1.2多态的形式

1.2.1父类对象引用子类实例

1.2.2父类作为方法形参实现多态(运行时多态)

public void feed(Pet pet){
        pet.eat();
    }
package com.chenlan03.poly1;

public class Test {
    public static void main(String[] args) {
        Master master = new Master("chenchen");
        Pet pet = null;
        pet = new Dog("lala", 90, 90, "拉布拉多犬");
        master.feed(pet);
        pet.showInfo();
        pet = new Penguin("heha", 80, 80, "Q仔");
        master.feed(pet);
        pet.showInfo();
    }
}

父类作为方法形参,在编译期间,无法得知pet执行的是谁的eat()方法,只有当程序运行时,实参才传递给形参,此时我们才知道pet到底是什么具体的子类。

1.2.3父类作为返回值实现多态

1.3多态类型转换

1.3.1自动类型转换

父类可以自动转换为子类,称为向上类型转换

 Pet pet = new Dog();

1.3.2强制类型转换

在多态中,父类引用子类时,无法调用子类独有的方法,所以要进行强制类型转换,称为向下类型转换

Pet pet = null;
Dog dog = (Dog) pet;

1.3.3instanceOf

用于判断一个运行时对象是否是指定的(父)类实例,返回boolean类型

package com.chenlan04.poly2;

public class Master {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Master() {
    }

    public Master(String name) {
        this.name = name;
    }

    public Pet adopt(int type){
        Pet pet = null;
        switch (type) {
            case 1:{
                pet = new Dog();
                break;
            }
            case 2:{
                pet = new Penguin();
                break;
            }
        }
        return pet;
    }
}
package com.chenlan04.poly2;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Master master = new Master("chenchen");
        Scanner sc = new Scanner(System.in);
        System.out.println("请选择要领养的宠物(1.狗狗 2.企鹅)");
        int type = sc.nextInt();
        Pet pet = master.adopt(type);
        pet.setName("lala");
        pet.setHealth(80);
        pet.setLove(80);
        if(pet instanceof Dog){
            Dog dog = (Dog) pet;
            dog.setStrain("拉布拉多犬");
        }else if(pet instanceof Penguin){
            Penguin penguin = (Penguin) pet;
            penguin.setGender("Q仔");
        }
        pet.showInfo();
    }
}

1.4多态总结

封装:保证类信息的安全性和正确性。

继承:减少重复性代码。

多态:提高程序的可拓展性、可维护性。

多态(Polymorphism)是面向对象编程语言的重要特性,它允许父类引用指向子类的对象,而在具体访问时实现方法的动态绑定。

多态的3个必要条件

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重写/实现,在调用这些方法时就会调用子类重写或实现方法。

向上转型(父引子):在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能执行子类的方法。

关于多态的理解:

在创建对象时,把左边的变量类型声明成它的父类,像Pet pet=new Dog()这样,左边是父类,右边是子类,左边表示编译类型,右边表示运行时类型,像这样编译类型和运行类型不同时,就出现多态

因为编译时期找的是父类,所以如果父类中没有我们调用的方法,那编译就会失败,程序就无法执行,而如果父类中有方法,但是子类没有重写,那编译会通过,且会执行父类中的方法,因为运行时它会去子类中找,找不到,再去父类中找,所以就会执行父类中的方法了

1.6接口

接口是一种引用数据类型,使用关键字interface

package com.chenlan01.interface1;

public interface AInterface {
    String name = "AInterface";
    //推荐写法
    public void print();
    /*void print();*/
    /*public abstract void print();*/
}

1.6.1接口的特性

【1】接口中可以定义属性,且默认是public static final类型

package com.chenlan01.interface1;

public class Test {
    public static void main(String[] args) {
        System.out.println(AInterface.name);
    }
}

20200904191221589

【2】接口中的方法都是public abstract方法

20200904191522357

package com.chenlan01.interface1;

public class ImplClassA implements AInterface {
    @Override
    public void print() {
        System.out.println("ImplClassA.print");
    }
}

【3】接口不是类,不能被实例化,不能定义构造方法

20200904192000089

【4】接口支持继承,且支持多继承,一个接口可以继承多个接口、

package com.chenlan01.interface1;

public interface CInterface extends AInterface,BInterface {

}

【5】一个类可以实现一个或多个接口。该类称为该接口的实现类、使用关键字implements,实现类必须实现接口中所有的抽象类方法。

package com.chenlan01.interface1;

public class ImplClassA implements AInterface {
    @Override
    public void print() {
        System.out.println("ImplClassA.print");
    }
}

【6】一个类可以继承一个父类实现多个接口,继承在前,实现在后

(要规避抽象父类与接口定义了相同的抽象方法,此时实现类实现的是父类的抽象方法)

package com.chenlan01.interface1;

public class ImplClassB extends ImplClassA implements BInterface {

    @Override
    public void showInfo() {
        System.out.println("ImplClassB.showInfo");

    }

}

接口规范了类的行为,拓展了类的行为

1.7接口的应用

1.7.1接口描述一种能力

接口描述的是一种能力,实现类必须实现接口中定义的能力,即实现类中具备了接口中定义的能力

1.7.2接口实现多态

接口可以实现多态。

【1】本质:接口 new 实现类实现多态

【2】多态的其他形式:接口作为方法形参,接口作为方法返回值

package com.chenlan03.interface3;

public interface DriverInterface {
    public void drive();
}
package com.chenlan03.interface3;

public class Student implements DriverInterface {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public void drive() {
        System.out.println(this.name + "正在开车");

    }
}
package com.chenlan03.interface3;

public class Teacher implements DriverInterface {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher() {
    }

    public Teacher(String name) {
        this.name = name;
    }

    @Override
    public void drive() {
        System.out.println(this.name + "正在开车");

    }
}
package com.chenlan03.interface3;

public class Test {
    public static void main(String[] args) {
        DriverInterface driverInterface = null;
        driverInterface = new Student("chenchen",12);
        driverInterface.drive();
        driverInterface = new Teacher("linlin");
        driverInterface.drive();
    }
}

1.7.3接口是一种约定

接口是一种约定,约定了实现类应该具备的能力。

接口只关心实现类是否具备接口中定义的能力,而不关心实现类如何具备的这个能力

1.7.4面向接口编程

完成大型系统时,通过接口实现模块间的解耦,这种编程思维称为面向接口编程。

接口与抽象类的区别:

【1】都是引用类型,都不能被实例化

【2】它们都可以定义抽象方法,都可以实现多态。但是抽象类可以定义非抽象方法,而接口中定义的只能是抽象方法

【3】抽象类和接口都有传递性,但抽象类是单继承,而接口是多继承

【4】抽象类和子类解决的是模块内的问题,而接口解决的是模块间的问题

1.8内部类

【1】类之间的平行关系

一个文件可以有多个类,但只能有一个公共类,而且公共类的类名要与文件名一致

package com.chenlan05.inner1;

public class Test {

}
class Test01{

}

【2】类之间的包含关系

package com.chenlan05.inner1;

public class Outer {
    public class inner{
        
    }
}

1.8.1成员内部类

内部类Inner作为外部类的一个成员存在,Inner称为成员内部类

【1】创建成员内部类对象

package com.chenlan05.inner1;

import com.chenlan05.inner1.Outer.Inner;

public class Demo {
    public static void main(String[] args) {
        Outer outer = new Outer();
        /*idea*/
        /*Outer.inner inner = outer.new Inner();*/
        Inner inner= outer.new Inner();
        inner.showInfo();
    }
}

【2】成员内部类特性

成员内部类可以直接访问外部类的私有成员

package com.chenlan05.inner1;

public class Outer {
    private String name = "Outer";

    public class Inner{
        //规避内部类与外部类定义了同名变量的情况
        String name = "Inner";
        public void showInfo(){
            System.out.println("inner.showInfo");
            /*访问内部类的变量*/
            System.out.println(name);
            System.out.println(this.name);
            /*访问外部类的变量*/
            System.out.println(Outer.this.name);
        }

    }
}

1.8.2静态内部类

静态内部类作为外部类的一个静态成员成员存在,静态内部类不会随着外部类的加载而加载

【1】创建静态内部类对象

package com.chenlan06.inner2;

import com.chenlan06.inner2.Outer.Inner;
public class Test {
    public static void main(String[] args) {
        /*idea*/
        /*Outer.Inner inner=new Outer.Inner();*/
        Inner inner = new Outer.Inner();
        inner.showInfo();
    }
}

【2】静态内部类特性

静态内部类可以访问外部类的私有静态成员

package com.chenlan06.inner2;

public class Outer {
    private static String name = "Outer";
    static class Inner {
        private  static String name = "Inner";
        void showInfo() {
            System.out.println("Inner.showInfo");
            System.out.println(name);
            System.out.println(Inner.name);
            System.out.println(Outer.name);
        }
    }
}

1.8.3方法内部类

当一个类存在于方法中时,构成方法内部类。方法内部类只能存在于方法中,同时也只能在方法中创建对象。

方法内部类前没有任何修饰符,因为内部类定义在方法中,都是局部存在的。

【1】创建方法内部类对象

方法内部类对象只可以在方法中创建

package com.chenlan07.inner3;

public class Outer {

    public void print() {
        int a = 10;
        class Inner {
            public void showInfo() {
                System.out.println("Inner.showInfo");
                /*方法内部类中访问了方法中的变量之后,jvm为变量加上了final关键字,变量不可修改*/
                System.out.println(a);
                /*方法内部类可以访问方法中的变量,但不能修改*/
                /*a = 20;*/
            }
        }
        /*a = 20;*/

        Inner inner = new Inner();
        inner.showInfo();
        /*匿名对象*/
        /*new Inner().showInfo();*/
    }
}

【2】方法内部类特性

方法内部类可以访问方法定义的局部变量,但不可以修改。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值