day12_ Introduction to object-oriented (inheritance, polymorphism) ④

Inheritance overview

Inheritance is one of the three characteristics of object-oriented. Encapsulation comes first. After encapsulation, an independent body is formed. There may be an inheritance relationship between independent body A and independent body B. In fact, the inspiration of inheritance in the program comes from real life. Inheritance can be seen everywhere in real life. For example, A son inherits his father's property and his son is rich without effort. Inheritance in life:

Why use inheritance?

  • Basic function: the subclass inherits the parent class, and the code can be reused. There may also be common features and actions in different classes. These common features and actions can be placed in one class and shared by other classes. Therefore, a general class can be defined and then extended to multiple other specific classes, which inherit the features and actions in the general class.
  • Important role: because of inheritance, there is later method coverage and polymorphism mechanism.

How to inherit

Inherited syntax format in java:

Inherited related properties

  1. If class B inherits from Class A, class A is called superclass, parent class and base class, and class B is called subclass, derived class and extended class.
  2. Inheritance in java only supports single inheritance, not multiple inheritance. C + + supports multiple inheritance, which is also a point of simplicity in java. In other words, it is not allowed to write code like this: Class B extensions a, C {}.
  3. Although multiple inheritance is not supported in java, sometimes it will have the effect of indirect inheritance, such as class Cextends B and class B extends A. in other words, C inherits B directly. In fact, C also inherits a indirectly.
  4. java stipulates that the subclass inherits from the parent class. Except that the constructor cannot inherit, the rest can inherit. However, private properties cannot be accessed directly in subclasses. (private modified in the parent class cannot be accessed directly in the child class. It can be accessed indirectly.)
  5. If a class in java does not inherit any classes, it inherits the Object class by default. The Object class is the root class (ancestral class) provided by the java language. That is, an Object is born with all the characteristics of the Object type.
  6. Inheritance also has some disadvantages. For example, CreditAccount class. Inheriting the Account class will lead to a very high degree of coupling between them. The CreditAccount class will be affected immediately after the Account class is changed.

Subclass objects call inherited methods and properties

In fact, the above question is a little strange!!!!! What's strange? "You can use a subclass object to call a parent method". In essence, after a subclass inherits the parent class, it owns the methods inherited from the parent class. In fact, what is called is not the method of the parent class, but the method of its own subclass (because it has been inherited, it belongs to itself. It is equivalent to copying a copy of the code outside the construction method in the parent class and pasting it into the subclass).

Code example
/*
Test: after the subclass inherits the parent class, can the subclass object be used to call the parent class method
    In fact, the above question is a little strange!!!!!
    What's strange? "Can use subclass objects to call parent methods"
    In essence, after a subclass inherits the parent class, it owns the methods inherited from the parent class.
    In fact, what is called is not the method of the parent class, but the method of its child class (because it has been inherited)
    It belongs to you.
        
*/
public class ExtendsTest04{
    public static void main(String[] args){
        // Create subclass object
        Cat c = new Cat();
        // Call method
        c.move();
        // Subclass object access name
        System.out.println(c.name);
    }
}

// Parent class
//class Animal extends Object {
class Animal{
    // Name (not encapsulated first)
    String name = "XiaoHua"; //The default value is not null,Give one XiaoHua

    // Provide a way for animals to move
    public void move(){
        System.out.println(name + "Moving!");
    }
}

// Cat Subclass
// Cat inherit Animal,Will Animal All of them are inherited.
class Cat extends Animal{
}

When to use inheritance?

Inheritance (Generalization, also known as Generalization, is-a relationship) can inherit anything that can be described by "is a". For example:
Cat is a Animal: A cat is an animal
Dog is a Animal: A dog is an animal
CreditAccount is a Account: A credit card account is a bank account

Object class

Any class (including array) does not inherit any class. It inherits Object by default. What methods are there in the Object class? What methods did our ancestors provide us? Let's check the source code of Object

//Default inheritance Object,Object What are the methods in the class?
/*
public class Object {
     
     // Note: when a method in the source code is marked with " And there is a "native" keyword in the modifier list
     // Represents the dll program written by the bottom layer calling C + + (dll Dynamic link library file)
    private static native void registerNatives();

     // Static code block
    static {
          // Call the registerNatives() method.
        registerNatives();
    }

     // Nonparametric construction method
    @HotSpotIntrinsicCandidate
    public Object() {}

     // The bottom layer also calls C++
    @HotSpotIntrinsicCandidate
    public final native Class<?> getClass();

     // The bottom layer also calls C++
    @HotSpotIntrinsicCandidate
    public native int hashCode();

     // equals You should be able to understand the method.
     // public It's public
     // boolean Is the return value type of the method
     // equals Is a method name: equal
     // (Object obj) Formal parameter
     // However, the significance of this method is still unknown.
    public boolean equals(Object obj) {
         //Method body
       return (this == obj);
    }
    
     // The object a already exists. To create an object exactly like a, you can call this cloning method.
     // The bottom layer also calls C++
    @HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

     // Later, we can test the toString() method.
     // public Indicates public
     // String Is the return value type. The toString() method returns a string after execution.
     // toString This is the method name.
     // () Indicates that the number of formal parameters is 0
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    @HotSpotIntrinsicCandidate
    public final native void notify();

    @HotSpotIntrinsicCandidate
    public final native void notifyAll();

    public final void wait() throws InterruptedException {
        wait(0L);
    }

    public final native void wait(long timeoutMillis) throws InterruptedException;

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }
    @Deprecated(since="9")
    protected void finalize() throws Throwable { }
}
*/
public class ExtendsTest05 {

    // ExtendsTest05 Default inheritance Object
    // ExtendsTest05 There are toString()method
    // however toString()Method is an instance method, which can only be called after creating an object.
    public static void main(String[] args){

        // Can the analysis code be executed?
        //ExtendsTest05.toString();

        // before new object
        ExtendsTest05 et = new ExtendsTest05();
        String retValue = et.toString();

        // 2f92e0f4 It can be regarded as the memory address of the object in the heap memory.
        // In fact, it is the hexadecimal result of the memory address through the "hash algorithm".
        System.out.println(retValue); // ExtendsTest05@2f92e0f4

        // create object
        Product pro = new Product();

        System.out.println(pro.toString()); //Product@5305068a

        // What if you directly output "reference"???????
        System.out.println(pro); //Product@5305068a

        System.out.println(100);
        System.out.println(true);
        // Product@5305068a
        System.out.println(pro); // println Method is called automatically pro of toString()method.
    }
}

Method coverage

What is method coverage?

In the subclass, you can modify the methods inherited from the parent class as needed, which is also called method reset and overwrite. When the program executes, the methods of the subclass will override the methods of the parent class.

When will we consider using "method override"?

After the subclass inherits the parent class, when the inherited method cannot meet the business needs of the current subclass, the subclass has the right to rewrite the method, and it is necessary to "Overwrite the method". Method coverage is also called method rewriting (Rewriting), and English words are called override and Overwrite. Common: Method override, method rewrite, override

Important conclusions:

When the subclass "overrides" the method inherited from the parent class and the subclass object calls the method, the method after the override must be executed.

Code example

Define the parent class Animal

package demo01;

public class Animal {
    public void move(){
        System.out.println("Animals are moving!");
    }
    public void sing(int i){
        System.out.println("Animal sing....");
    }
}

Define subclass Bird

package demo01;

class Bird extends Animal {

    // yes move Method, method override, override
    // It's best to copy the methods in the parent class intact. (manual writing is not recommended)
    // Method override is to override the inherited method. The inherited method is gone.
    public void move() {
        System.out.println("Birds are flying!!!");
    }
    // Analysis: this sing()And in the parent class sing(int i)Is there a method coverage?
    // No, the reason is that these two methods are completely different.
    // Can we say that these two methods constitute method overloading? sure.
    public void sing(){
        System.out.println("Bird sing.....");
    }
}

Define subclass Cat

package demo01;
class Cat extends Animal{

    // Method rewrite
    public void move(){
        System.out.println("The cat is walking cat steps!!!");
    }
}

Define test class

package demo01;

public class OverrideTest02 {
    public static void main(String[] args){
        Bird b = new Bird();
        b.move();//Birds are flying!!!
        b.sing(1000); //Animal sing....

        Cat c = new Cat();
        c.move();//The cat is walking cat steps!!!
    }
}

How do we write code that constitutes method coverage at the code level?

  • Condition 1: two classes must have inheritance relationship.
  • Condition 2: the rewritten method and the previous method have:
    • The return value type of the method overridden by the subclass cannot be greater than the return value type of the method overridden by the parent class. 99% of them are the same.
    • Same method name
    • The same form parameter list.
  • Condition 3: the access authority cannot be lower, but higher. (remember this first.)
  • Condition 4: the rewritten method cannot throw more exceptions than the previous method, and can throw fewer exceptions. (remember this first)

Here are some other precautions:

  • Note 1: method overrides are only for methods and have nothing to do with attributes.
  • Note 2: private methods cannot be overridden.
  • Note 3: construction methods cannot be inherited, so construction methods cannot be overwritten.
  • Note 4: Method coverage is only for "instance method", and "static method coverage" is meaningless.
/*
    1,Method coverage needs to be combined with polymorphism mechanism to make sense.
        Animal a = new Cat();
        a.move();
        What effect do you want?
            When compiling, the move() method is Animal.
            Automatically call the subclass override move() method when running.
        
        Do you think it makes sense to assume that there is no polymorphism mechanism and only method coverage mechanism?
            If there is no polymorphism mechanism, method coverage is optional.

            If there is no polymorphism mechanism, method coverage can also be absent. If the method of the parent class cannot be satisfied
            When subclasses meet business requirements, subclasses can completely define a new method.
        
        Method coverage and polymorphism cannot be separated.

    2,Do static methods have method overrides?
        Polymorphism is naturally related to objects.
        The execution of static methods does not require objects.
        Therefore, in general, we will say that static methods "do not exist" method coverage.
        The coverage of static methods is not discussed.

*/
public class OverrideTest05{
    public static void main(String[] args){
        // Static methods can use reference."To call? sure
        // Although "reference" is used."To call, but it has nothing to do with the object.
        Animal a = new Cat(); //polymorphic
        // Static methods are object independent.
        // Although "reference" is used."To call. However, in actual operation: Animal.doSome()
        a.doSome();
        
        Animal.doSome();
        Cat.doSome();
    }
}

class Animal{
    // Static method of parent class
    public static void doSome(){
        System.out.println("Animal of doSome Method execution!");
    }
}

class Cat extends Animal{
    // Try overriding the static method of the parent class in a subclass
    public static void doSome(){
        System.out.println("Cat of doSome Method execution!");
    }
}

When subclass objects call this method, they must execute the method after overwriting.

Override the toString method in the Object class

  • public String toString(): returns the string representation of the object.

The toString method returns the string representation of the object. In fact, the content of the string is the type + @ + memory address value of the object. Because the result returned by toString method is the memory address, and in development, it is often necessary to get the corresponding string representation according to the object properties, so it also needs to be rewritten. If you do not want to use the default behavior of the toString method, you can override it.

In IntelliJ IDEA, click Generate... In the Code menu, You can also use the shortcut key alt+insert and click the toString() option. Select the member variables to include and confirm. As shown in the figure below:
Tip: when we directly use the output statement to output the object name, we actually call its toString() method through the object.

polymorphic

In life, such as running, kittens, dogs and elephants run differently. Another example is the action of flying, insects, birds and aircraft are also different. It can be seen that the same behavior can reflect different forms through different things. Polymorphism describes such a state. Polymorphism: refers to the same behavior with multiple different manifestations.

premise

  • Inherit or implement [one of two]
  • Rewriting of methods [meaning embodiment: no rewriting, meaningless]
  • The parent class reference points to the child class object [format representation]

Object polymorphism: it can be directly applied to abstract classes and interfaces. When calling a method in a polymorphic way, first check whether there is the method in the parent class. If not, there will be a compilation error; If yes, the method after subclass override is executed

There are two types of Java reference variables: compile time type and runtime type. The compile time type is determined by the type used when declaring the variable, and the runtime type is determined by the object actually assigned to the variable. Abbreviation: when compiling, look at the left; When running, look to the right.

If compile time type and run-time type are inconsistent, object polymorphism occurs
In the case of polymorphism,
  • The method in the reference is unique to the child class (see the parent class in the reference on the left)
  • "Look to the right": look at the objects of the subclass (actually running the method of overriding the parent class by the subclass)
Polymorphism of objects - in Java, objects of subclasses can be used instead of objects of parent classes
  • A variable can only have one definite data type
  • A reference type variable may point to (Reference) many different types of objects
A method with the same name and parameters as the parent class is defined in the subclass. In the case of polymorphism, the method of the parent class at this time is called a virtual method. The parent class dynamically calls the method belonging to the subclass according to the different subclass objects assigned to it. Such method calls cannot be determined at compile time.

Reference type conversion

Polymorphic transformation can be divided into upward transformation and downward Transformation:

Upward transformation

Upward Transformation: the subclass can be regarded as a special parent class, so the reference of the parent type can point to the object polymorphism of the subclass. Polymorphism itself is the process of upward transformation from the subclass type to the parent type, which is the default. When the parent class reference points to a subclass object, it is an upward transformation. Parent class type: refers to the parent class type inherited by the child class object or the implemented parent interface type. This situation is the embodiment of polymorphism.
  • Usage format: parent type variable name = new subclass type ();

Disadvantages of polymorphism

  • When calling a method in a polymorphic way, first check whether the method exists in the parent class. If not, there will be a compilation error. In other words, you cannot call methods that are owned by a subclass but not by a parent class. Compilation errors, let alone running. This is also a little "trouble" brought by polymorphism. Therefore, if you want to call subclass specific methods, you must make a downward transformation.

Downward transformation

Downward Transformation: the process of downward transformation from parent type to child type. This process is mandatory. For a subclass object that has been transformed upward, the parent class reference can be transformed into a subclass reference. The format of forced type conversion can be used, that is, downward transformation.
  • Usage format: subclass type variable name = (subclass type) parent class variable name;

Code example

package demo02;

// Animals: parent
public class Animal{

    // Method of moving
    public void move(){
        System.out.println("Animals are moving!!!");
    }

}

Define subclass Cat

package demo02;

// Cat, subclass
public class Cat extends Animal{

    // yes move Method
    public void move(){
        System.out.println("cat Catwalk!");
    }

    // Cat except move Besides, they should have their own unique behavior, such as catching mice.
    // This behavior is specific to subtype objects.
    public void catchMouse(){
        System.out.println("The cat is catching mice!!!!");
    }

}

Define subclass Bird

package demo02;

// Birds, subclasses
public class Bird extends Animal{

    // Override the of the parent class move method
    public void move(){
        System.out.println("Birds are flying!!!");
    }

    // It also has its own unique method
    public void sing(){
        System.out.println("Birds are singing!!!");
    }

}

Define a separate class Dog

package demo02;

// Dog No inheritance Animal
// Dog no Animal Subclass of
public class Dog{

}

Define test class

package demo02;

/*
    Polymorphic basic syntax:
        1,Before learning polymorphic basic grammar, we need to popularize two concepts:
            First: upward transformation
                Child -- > parent (automatic type conversion)
            Second: downward transformation
                Parent -- > child (casts, casts are required)

            be careful:
                java China allows upward transformation and downward transformation.

                *****(Five stars) whether it's up or down,
                        There must be an inheritance relationship between the two types. If there is no inheritance relationship, the compiler will report an error.
                
                In the future, in the process of work, when chatting with others, be more professional and say
                Upward transformation and downward transformation, not to mention automatic type conversion, not to mention mandatory
                Type conversion, because automatic type conversion and cast type conversion are used in basic
                In terms of data types, there are only upward and downward transformations in reference type conversion.
        
        2,Polymorphism refers to:
            A parent type reference points to a child type object.
            Including compilation phase and running phase.
            Compile phase: bind the method of the parent class.
            Run phase: the method of dynamically binding subtype objects.
            Various forms.
        
        3,Some students are a little confused:
            java Only "class name" or "reference" can go to "point" in
            Class name
            quote.
            As long as you want to "point", the front of "point" is either a class name or a reference.
        
        4,When does "downward transformation" have to be used?
            Don't cast casually.
            When you need to access "unique" methods in subclass objects. At this point, we must make a downward transformation.
*/
public class Test01{

    public static void main(String[] args){

        Animal a1 = new Animal();
        a1.move(); //Animals are moving!!!

        Cat c1 = new Cat();
        c1.move(); //cat Catwalk!

        Bird b1 = new Bird();
        b1.move(); //Birds are flying!!!

        // Can the code be written like this?
        /*
            1,Animal Is there an inheritance relationship with Cat? yes , we have.
            2,Animal Cat is a parent class and cat is a child class.
            3,Cat is a Animal,Can this sentence make sense? Yes.
            4,After testing, we know that java supports such a syntax:
                A reference to a parent type allows you to point to objects of a child type.
                Animal a2 = new Cat();
                a2 Is a reference to the parent type.
                new Cat()Is a subtype object.
                Allow a2 this parent type to refer to an object of a child type.
        */
        Animal a2 = new Cat();
        Animal a3 = new Bird();

        // Is there a transition between two types without inheritance?
        // error: Incompatible types: Dog Cannot convert to Animal
        // Animal a4 = new Dog();

        // call a2 of move()method
        /*
            What is polymorphism?
                Various forms and states.
            Analysis: A2 move();
                java The program is divided into compilation stage and running stage.
                Let's analyze the compilation phase first:
                    For the compiler, the compiler only knows that the type of a2 is Animal,
                    So when the compiler checks the syntax, it will go to animal class
                    Find the move() method in the bytecode file. If it is found, bind to move()
                    Method. The compilation passes and the static binding succeeds. (the compilation phase is a static binding.)
                Then analyze the operation phase:
                    During the run phase, the java objects actually created in heap memory are
                    Cat Object, so when moving, the object that really participates in moving is a cat,
                    Therefore, the runtime will dynamically execute the move() method of the Cat object. This process
                    It belongs to runtime binding. (runtime binding is a dynamic binding.)

            Polymorphisms represent multiple forms:
                A form when compiling.
                Another form when running.
        */
        a2.move(); //cat Catwalk!
        
        // call a3 of move()method
        a3.move(); //Birds are flying!!!

        // ======================================================================
        Animal a5 = new Cat(); // The underlying object is a cat.

        // Analyze whether this program can be compiled and run?
        // The analyzer must analyze the static binding in the compilation stage and the dynamic binding in the running stage.
        // Only compiled code can run. Without compilation, it can't run at all.
        // error: Symbol not found
        // why??? Because the compiler only knows a5 The type of is Animal,go Animal.class Found in file catchMouse()method
        // The result was not found, so the static binding failed and the compilation reported an error. Cannot run. (illegal syntax.)
        //a5.catchMouse(); 
        
        // If the code is written here, I have to call it catchMouse()What about the method?
        // At this time, we must use "downward transformation". (CAST)
        // Why is there no error in the following line of code????
        // because a5 yes Animal Type, convert to Cat,Animal and Cat There is an inheritance relationship between. So there's no mistake.
        Cat x = (Cat)a5;
        x.catchMouse(); //The cat is catching mice!!!!

        // Is there a risk of downward transformation?
        Animal a6 = new Bird(); //On the surface a6 It's a Animal,It's actually a bird when it's running.
        /*
            Analyze the following programs, compile and report errors or run them???
                The compiler has detected that a6 this reference is of type Animal,
                There is an inheritance relationship between Animal and Cat, so it can be transformed downward.
                There's nothing wrong with the compilation.

                In the run phase, the object actually created in heap memory is Bird object.
                In the actual running process, hold the Bird object and convert it into Cat object
                Not anymore. Because there is no inheritance relationship between Bird and Cat.
            
            An exception occurs during operation. This exception is as important and classic as the null pointer exception:
                java.lang.ClassCastException: Type conversion exception.
            
            java.lang.NullPointerException: Null pointer exception. This is also very important.
        */
        //Cat y = (Cat)a6;
        //y.catchMouse();

        // How to avoid ClassCastException Abnormal occurrence???
        /*    
            New content, operator:
                instanceof (Operation phase (dynamic judgment)
            The reference type of instanceof can be determined dynamically in the first stage.
            Second: the syntax of instanceof:
                (Reference instanceof type)
            Third: the operation result of instanceof operator can only be: true/false
            Fourth: c is a reference. The c variable holds the memory address and points to the object in the heap.
                If (c instanceof Cat) is true, it means:
                    c The java object in heap memory that the reference points to is a Cat.
                If (c instanceof Cat) is false, it means:
                    c The java object in heap memory that the reference points to is not a Cat.
            
            Programmers should form a good habit:
                At any time, at any place, when making a downward transformation of a type, it must be used
                instanceof Operator. (required in the java specification.)
                This can be avoided: ClassCastException
        */
        System.out.println(a6 instanceof Cat); //false

        if(a6 instanceof Cat){ // If a6 It's a Cat
            Cat y = (Cat)a6;  // Then cast
            y.catchMouse();
        }
    }
}

Benefits of polymorphism

In the actual development process, the parent type is used as the formal parameter of the method, passing the subclass object to the method and calling the method, which can better reflect the expansibility and convenience of polymorphism. Let's first understand a business background: please design a system to describe the scene of pet feeding. Firstly, there should be a "pet object", which should have a eating behavior. In addition, there should be a "master object", which should have a feeding behavior,
Define parent class
package demo03Teacher;

// Parent of all pets
public class Pet {

    // Eating behavior (this method can be implemented without specific.)
    public void eat() {

    }


}

Define subclass Dog

package demo03Teacher;

// Pet dogs
public class Dog extends Pet{
    // eat
    public void eat(){
        System.out.println("Dogs like to chew bones and eat very delicious.");
    }
}

Define subclass Cat

package demo03Teacher;

public class Cat extends Pet{

    // eat
    public void eat(){
        System.out.println("Cats like to eat fish, eat very delicious!!!");
    }
}

Define subclass parrot

package demo03Teacher;

public class parrot extends Pet{

    //rewrite eat method
    public void eat(){
        System.out.println("Parrots like to eat small insects, eat very fragrant!!!");
    }

}

Define the main human

package demo03Teacher;

// Lord human
public class Master{

    /*
    // Suppose the owner just likes to keep a pet dog at first
    // Feeding pet dogs
    public void feed(Dog d){
        d.eat();
    }

    // Due to the new requirements, we have to modify the code of the Master class
    public void feed(Cat c){
        c.eat();
    }
    */
    
    // Can you let Master The master class will not be modified in the future.
    // Even if the owner likes to keep other pets again, Master There is no need to modify.
    // At this time, we need to use: polymorphism mechanism.
    // It's best not to write specific pet types, which will affect the scalability of the program.
    public void feed(Pet pet){ 
        // When compiling, the compiler found that pet yes Pet Class, will go Pet Find in class eat()Method. The result is found and compiled
        // When running, what is the actual object at the bottom will be automatically called to the corresponding object of the actual object eat()Method.
        // This is the use of polymorphism.
        pet.eat();
    }

}

/*

    Note the analysis here:
        At first, the owner only liked to keep pet dogs
        With the passage of time, the owner likes to keep "Cats"
        In the actual development, this means that customers have new requirements.
        As software developers, they must meet the needs of customers.
        How can we meet the needs of customers?
            At present, we can only add a new method to the Master class without using the polymorphism mechanism.
    
    Thinking: what is the problem of modifying the Master class in the process of software expanding new requirements?
        It must be remembered that the less the software is modified in the process of expansion, the better.
        The more changes you make, the worse the current stability of your system and the more unknown risks.

        In fact, this involves a software development principle:
            There are seven principles for software development (not java, which belongs to the whole software industry):
                One of the most basic principles is OCP (opening and closing principle)

        What is the opening and closing principle?
            Open to extensions (you can add extra, no problem), close to modifications (it's best to modify existing programs very little).
            In the process of software expansion, the less you modify, the better.
    

    Expert development projects are not only to meet the needs of customers, but also need to consider the scalability of software.

    What is software scalability?
        Suppose the memory module in the computer is broken, we can buy a new one to plug in and use it directly.
        The computer is designed with "scalability" in mind. The memory module has good scalability.
    
    Programming for parent type is more abstract, and programming for concrete is not recommended.
    Because concrete oriented programming will make the expansion of software very poor.

*/

Define test class

package demo03Teacher;

/*
    The role of testing polymorphism in development
*/
public class Test{
    public static void main(String[] args){
        // Create master object
        Master zhangsan = new Master();
        // Create pet object
        Dog zangAo = new Dog();
        // Hello, master
        zhangsan.feed(zangAo);//Dogs like to chew bones and eat very delicious.
        // Create pet object
        Cat xiaoHua = new Cat();
        // Hello, master
        zhangsan.feed(xiaoHua);//Cats like to eat fish, eat very delicious!!!
        // Create pet object
        parrot yingWu = new parrot();
        // Hello, master
        zhangsan.feed(yingWu);//Parrots like to eat small insects, eat very fragrant!!!
    }
}
In the above program, the parameter type of the method feed(Pet pet) in the Master class is defined as a more abstract Pet type, rather than a specific Dog Pet or Cat Pet. Obviously, the Master class is decoupled from the specific Dog and Cat classes, and the dependency is weak. This is what we usually call Abstract oriented programming. Try not to face concrete programming. Abstract oriented programming will reduce the coupling of your code and enhance your expansion ability, So as to comply with the development principles of OCP. If there is another new Pet Pig, we just need to add a new "Pet Pig", and then the Pet Pig pig inherits the Pet class Pet, rewrites the eat() method, and then modifies the test class. In the whole process, we don't need to modify the Master class, but add a new class

summary

We can see that polymorphism is used together with method coverage in development, which can reduce the coupling degree of the program and improve the expansion force of the program. As far as possible, the development should be oriented towards abstract programming, not concrete programming

Polymorphism:
  • It improves the generality of code, which is often called interface reuse
Premise:
  • Inheritance or implementation relationship is required
  • Methodical rewriting
Member method:
  • Compile time: check whether there are methods called in the class declared by the reference variable.
  • Runtime: calls the overriding method in the class to which the actual new object belongs.
Member variables:
  • It does not have polymorphism. It only depends on the class declared by the reference variable

 

Tags: JavaSE

Posted by NeMoD on Sun, 08 May 2022 12:13:39 +0300