Novice Xiaobai learns JAVA object-oriented polymorphism

polymorphism

1. Concept

Polymorphism is an important feature of object-oriented programming (OOP), which means that the same entity has multiple forms at the same time, that is, the same object, at different times, represents different objects, referring to multiple forms of objects.

Different subclass objects can be regarded as the parent class, and then the differences between different subclass objects can be shielded, common code can be written, common programming can be made, and calling standards can be unified.

For example, if your girlfriend asks you to buy some fruit, it doesn’t matter if it’s an apple or a watermelon, as long as it’s fruit, this is a manifestation of polymorphism in life

For another example, we can classify kittens, puppies, and piglets into small animals. Each small animal needs to eat, so we can uniformly set that they all must eat, but each small animal has different habits. Then this can be set as the unique function of the small animal itself. The polymorphic object can only call the function rewritten in the subclass defined in the parent class, and cannot call the unique function of the subclass, thus realizing the unification of the code

2. Features

  1. Premise 1 of polymorphism: inheritance
  2. Premise 2 of polymorphism: There must be method rewriting
  3. The parent class reference points to the subclass object, such as: Animal a = new Cat();
  4. In polymorphism, compile to the left and run to the right
    insert image description here

3. Exercise: Polymorphism Introductory Case

Create package: cn.tedu.oop
Create class: TestDemo.java

package cn.tedu.oop2;
/*本类用作多态的入门案例*/
public class TestDemo {
    
    
    public static void main(String[] args) {
    
    
        //6.创建“纯纯的”对象用于测试
        Animal a = new Animal();
        Cat c = new Cat();
        Dog d = new Dog();
        a.eat();//小动物Animal吃啥都行~调用的是父类自己的功能
        c.eat();//小猫爱吃小鱼干~调用的是子类重写后的功能
        d.eat();//小狗爱吃肉骨头~调用的是子类重写后的功能
        /*2.父类对象不可以使用子类的特有功能*/
        //a.jump();//报错,Animal类里并没有这个方法
        //a.run();//报错,Animal类里并没有这个方法
        c.jump();//小猫Cat跳的老高啦~,子类可以调用自己的功能
        d.run();//小狗Dog跑的老快啦~,子类可以调用自己的功能

        //7.创建多态对象进行测试
        /*3.口诀1:父类引用指向子类对象
        * 解释:创建出来的子类对象的地址值,交给父类类型的引用类型变量来保存*/
        Animal a2 = new Cat();//Cat类对象的地址值交给父类型变量a2来保存
        Animal a3 = new Dog();//Dog类对象的地址值交给父类型变量a3来保存
        //8.测试多态对象
        /*4.口诀2:编译看左边,运行看右边
        * 解释:必须要在父类定义这个方法,才能通过编译,把多态对象看作是父类类型
        *      必须要在子类重写这个方法,才能满足多态,实际干活的是子类*/
        a2.eat();//小猫爱吃小鱼干~,多态对象使用的是父类的定义,子类的方法体
    }
}
/*1.多态的前提:继承+重写*/
//1.创建父类
class Animal{
    
    
    //3.创建父类的普通方法
    public void eat(){
    
    
        System.out.println("小动物Animal吃啥都行~");
    }
}
//2.1创建子类1
class Cat extends Animal{
    
    
    //4.1添加重写的方法
    public void eat(){
    
    
        System.out.println("小猫爱吃小鱼干~");
    }
    //5.1添加子类的特有功能
    public void jump(){
    
    
        System.out.println("小猫Cat跳的老高啦~");
    }
}
//2.2创建子类2
class Dog extends Animal{
    
    
    //4.2添加重写的方法
    @Override
    public void eat(){
    
    
        System.out.println("小狗爱吃肉骨头~");
    }
    //5.2添加子类的特有功能
    public void run(){
    
    
        System.out.println("小狗Dog跑的老快啦~");
    }
}

4. The benefits of polymorphism

  1. Polymorphism allows us to use certain methods of an object without caring about the specific type of the object
  2. Improved program scalability and maintainability

5. The use of polymorphism

Premise: Polymorphic objects see themselves as parent types

  1. Member variables: use the parent class
  2. Member method: Due to the phenomenon of overriding, the subclass is used
  3. Static member: loaded with the loading of the class, whoever calls it will return

6. Exercise: polymorphic member usage test

Create package: cn.tedu.oop
Create class: TestDemo2.java

package cn.tedu.oop2;
/*本类用于测试多态成员的使用情况*/
public class TestDemo2 {
    
    
    public static void main(String[] args) {
    
    
        //7.创建纯纯的子类对象
        Dog2 d = new Dog2();
        System.out.println(d.sum);//20,子类自己的属性
        d.eat();//小狗爱吃肉包子,子类自己的方法

        //8.创建多态对象
        /*口诀1:父类引用指向子类对象*/
        /*口诀2:编译(保存)看左边,运行(效果)看右边*/
        Animal2 a = new Dog2();
        /*多态中,成员变量使用的是父类的*/
        System.out.println(a.sum);//10
        /*多态中,方法的声明使用的是父类的,方法体使用的是子类的*/
        a.eat();//小狗爱吃肉包子
        /*多态中,调用的静态方法是父类的,因为多态对象把自己看作是父类类型
        * 直接使用父类中的静态资源*/
        a.play();//没有提示,玩啥都行~
        Animal2.play();
    }
}
//1.创建父类
class Animal2{
    
    
    //3.创建父类的成员变量
    int sum = 10;
    //4.创建父类的普通方法
    public void eat(){
    
    
        System.out.println("吃啥都行~");
    }
    //9.1定义父类的静态方法play
    public static void play(){
    
    
        System.out.println("玩啥都行~");
    }
}
//2.创建子类
class Dog2 extends Animal2{
    
    
    //5.定义子类的成员变量
    int sum = 20;
    //6.重写父类的方法
    @Override
    public void eat(){
    
    
        System.out.println("小狗爱吃肉包子");
    }
    //9.2创建子类的静态方法play
    //@Override
    /*这不是一个重写的方法,只是恰巧在两个类中出现了一模一样的两个静态方法
    * 静态方法属于类资源,只有一份,不存在重写的现象
    * 在哪个类里定义,就作为哪个类的资源使用*/
    public static void play(){
    
    
        System.out.println("小狗喜欢玩皮球~");
    }
}

7 expansion

7.1 Comprehensive case of designing a car

Create package: cn.tedu.oopexec
Create class: DesignCar.java

package cn.tedu.oop2;
/*本类用于完成汽车设计案例*/
public class DesignCar {
    
    
    public static void main(String[] args) {
    
    
        //9.创建一个纯纯的父类对象进行测试
        Car c = new Car();
        System.out.println(c.getColor());//null
        c.start();
        c.stop();
        //c.swim();//报错,父类对象不可以调用子类的特有功能

        //10.创建纯纯的子类对象做测试
        BMW b = new BMW();
        System.out.println(b.color);//五彩斑斓的黑
        System.out.println(b.getColor());//null
        b.start();//都让开,我的车要起飞啦~
        b.stop();//唉呀妈呀熄火了~

        //11.创建多态对象进行测试
        Car c2 = new TSL();
        //System.out.println(c2.color);
        System.out.println(c2.getColor());
        c2.stop();
        c2.start();
        //c2.swim();
    }
}
//1.通过分析,抽象形成一个汽车类
class Car{
    
    
    //2.定义并封装汽车类的属性--成员变量
    private String brand;//品牌
    private String color;//颜色
    private int id;//编号
    private double price;//价格

    //3.定义功能
    public void start(){
    
    
        System.out.println("我的小车车启动啦~");
    }
    public void stop(){
    
    
        System.out.println("唉呀妈呀熄火了~");
    }

    public String getBrand() {
    
    
        return brand;
    }

    public void setBrand(String brand) {
    
    
        this.brand = brand;
    }

    public String getColor() {
    
    
        return color;
    }

    public void setColor(String color) {
    
    
        this.color = color;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public double getPrice() {
    
    
        return price;
    }

    public void setPrice(double price) {
    
    
        this.price = price;
    }
}

//4.创建子类
class BMW extends Car{
    
    
    String color = "五彩斑斓的黑";
    //5.重写父类的方法
    @Override
    public void start(){
    
    
        System.out.println("都让开,我的车要起飞啦~");
    }
}
//6.创建子类2
class TSL extends Car{
    
    
    //7.重写父类的方法
    @Override
    public void stop(){
    
    
        System.out.println("唉呀妈,怎么停不下来呢");
    }
    //8.添加子类的特有功能
    public void swim(){
    
    
        System.out.println("没想到吧,我还是个潜水艇");
    }
}

7.2 Polymorphism for unified call standard

package cn.tedu.oop2;

public class TestFruit {
    
    
    public static void main(String[] args) {
    
    
        Fruit f = new Fruit();
        Apple a = new Apple();
        Orange o = new Orange();
        get(f);
        get(a);
        get(o);
    }
    //只需要创建一个方法,就可以执行截然不同的效果
    //忽略子类对象的差异统一看作父类类型
    public static void get(Fruit f){
    
    
        f.clean();
    }
}
class Fruit{
    
    
    public void clean(){
    
    
        System.out.println("水果要洗洗再吃");
    }
}
class Apple extends Fruit{
    
    
    @Override
    public void clean(){
    
    
        System.out.println("苹果需要削皮");
    }
}
class Orange extends Fruit{
    
    
    @Override
    public void clean(){
    
    
        System.out.println("橙子需要剥皮");
    }
}

7.3 The difference between static variables and instance variables

The difference in grammatical definition: the static keyword should be added before the static variable, but not before the instance variable.
The difference when the program is running: the instance variable belongs to the attribute of an object, the instance object must be created, the instance variable in it will be allocated space, and the instance variable can be used. Static variables do not belong to an instance object, but belong to a class, so they are also called class variables. As long as the program loads the bytecode of the class, there is no need to create any instance object, the static variable will be allocated space, and the static variable can be used. In short, instance variables must be created before they can be used through this object, and static variables can be directly referenced using the class name.

7.4 Upward transformation and downward transformation

In JAVA, inheritance is an important feature. Through the extends keyword, subclasses can reuse the functions of the parent class. If the parent class cannot meet the needs of the current subclass, the subclass can rewrite the methods in the parent class to improve expand.
Then there are polymorphic applications in this process. There are two ways of transformation, namely: upward transformation and downward transformation.
Upward transformation: Different subclass objects can be regarded as parent classes, and then the differences between different subclass objects can be shielded, common code can be written, common programming can be made, and standard calling can be unified.
For example: parent class Parent, subclass Child
parent class reference points to the subclass object: Parent p=new Child();
Explanation: During upward transformation, the subclass object is regarded as the parent class object, and only the functions of the parent class can be called. The class overrides the method declared in the parent class, and the method body executes the function of the subclass after rewriting. But at this time, the object regards itself as the parent type, so other resources still use the parent type.
For example: Hua Mulan joined the army instead of her father. Everyone regards Hua Mulan as her father, but it is Hua Mulan who actually joins the army. Moreover, Hua Mulan can only do what her father can do, and she is not allowed to wear makeup in the army camp.

Downward transformation (less): The subclass reference points to the subclass object, and mandatory transformation must be taken during the process. This is because the subclass object that has been upcast before still wants to perform the unique functions of the subclass, so it needs to be restored to the subclass object
Parent p = new Child();//Upcast, at this time, p is the Parent type
Child c = (Child)p;//At this time, converting the Parent type p into a small type Child is
actually equivalent to creating a subclass object, you can use the parent class, or you can use your own
description: when converting downward, It is for the convenience of using the special method of the subclass, that is to say, when the function of the subclass method is expanded, the function of the subclass can be used directly.
For example: Hua Mulan's war is over, she no longer needs to be regarded as her father, and can "face the mirror with yellow decals"

Guess you like

Origin blog.csdn.net/weixin_43884234/article/details/116593803