Summary of Java knowledge points [5] Inheritance composition polymorphism

Object-oriented features: classes and objects, abstraction, encapsulation, inheritance, composition, polymorphism, reflection... Among them, the "three major features" refer to encapsulation, inheritance and polymorphism. Below we summarize inheritance, composition and polymorphism~

inherit

1. What is inheritance

If there is "duplicate code" in the code, it often means a certain risk. When we want to modify this "duplicate code", we may have to modify many places, resulting in a decrease in the maintainability of the code.

In order to avoid this, you can use an important usage in object-oriented-inheritance

The purpose of inheritance is code reuse and class reuse . Among the plurality of classes common code (common feature) extracted, into the "parent" , and then by the various subclasses inherit the parent class, respectively, will have sub-class attributes and methods of the parent class, which can be Eliminate duplicate codes. The keyword used is extends .

The inherited class is called the parent class/base class/super class, and the inherited class is called the subclass/derived class.

2. Example Animal Cat Bird

① We found that kittens and birds have common characteristics: name, food. Then these characteristics can be written in a class to represent the parent class. as follows:

class Animal{
    String name;
    public Animal(String name){
        this.name=name;
        System.out.println("Animal的构造方法");
    }
    public void eat(){
        System.out.println(this.name+"正在吃");
    }
}

②Cat can inherit from Animal, so that it has the name attribute and eat() method without repeating the definition. For other features of kittens, you can continue to add other functions, for example, kittens can jump~

class Cat extends Animal{
    public Cat(String name){
        super(name);  //必须放到第一行
        System.out.println("Cat的构造方法");
    }
    public void jump(){
        System.out.println(this.name+"正在跳");
    }
}

③Bird is based on Animal and adds the function of flying~

class Bird extends Animal{
    public Bird(String name){
        super(name);  //必须放到第一行
        System.out.println("Bird的构造方法");
    }
    public void fly(){
        System.out.println(this.name+"正在飞");
    }
}

④ Let’s test whether a new instance of a subclass has the functions of a parent class

public class Main{
    public static void main(String[] args) {
        Cat cat=new Cat("小狸花");
        cat.eat();
        cat.jump();
        Bird bird=new Bird("小鸟");
        bird.eat();
        bird.fly();
    }
}

operation result

Analysis: We have created instances of Cat and Bird respectively, and we can find that the eat() method is not written in these two classes, but is defined in the parent class Animal, but we can successfully call it, so it is indeed true through inheritance Can have the functions of the parent class~

But there is a problem. We can see from the results that when creating a Cat instance, first the constructor of the parent class Animal is called, followed by the constructor of the subclass Cat. In fact, when we go to a new Cat instance, we will first create an Animal instance ( inside Cat ), that is, when constructing a subclass instance, an instance of the parent class will be automatically constructed inside the subclass instance (As shown in the figure below), the construction method is called when the instance is created, so it is not difficult to understand it now~

Attentive friends may also find that there is the keyword super in the construction method of the subclass above. You can use the super keyword to get the reference of the instance of the parent class , and to get the reference of the subclass instance, use the this keyword.

note:

Every class has a constructor. If we don’t show the creation of a constructor, the compiler will automatically generate a constructor with no parameters for this class.

When no constructor is written in the parent class, a constructor with no parameter version is automatically generated. At this time, if the new subclass instance is called, the no-argument version of the construction method of the parent class just now will be called.

When there is a constructor in the parent class, and this constructor has parameters, the compiler will no longer customize the non-parameter version of the constructor. At this time, to create a subclass instance, you need to explicitly call the parent class's construction method and pass parameters, otherwise the parent class instance cannot be created, and a compilation error will occur. Modifying this problem is also very simple, as long as in the subclass's construction method, display the call to the parent class's construction method (using the super keyword).

3. Other points of attention

Inheritance in Java is single inheritance . A class can only have one parent class, but this parent class can also inherit from other classes.

The child class inherits all the properties and methods of the parent class, whether public or private. However, private modified members are not accessible in subclasses. (Modified by private can only be accessed inside the class, even if it is your own subclass)

Final modifies a variable, which means a constant (cannot be modified); final modifies a class, means that the modified class is forbidden to be inherited and prevents inheritance from being abused.


combination

1. What is a combination

Combination is also for code reuse. The members of one class can also be instances of other classes   .

After understanding inheritance, take the above example as an example: a kitten is an animal, and a bird is an animal. The semantics of inheritance can be understood as is-a .

The semantics of composition can be understood as: has-a . For example, we take a school as an example. The school contains a number of students and teachers.

2. Example

①The school contains two students and two teachers

class Teacher{
    String name;
    String subject;
}
class Student{
    String name;
    String num;
}
public class School{
    public Teacher[] teacher=new Teacher[2];
    public Student[] student=new Student[2];
}

②The circle contains the origin and radius

class Point{
    
}
class Raduis{
    
}
public class Circle {
    Point point=new Point();
    Raduis raduis=new Raduis();
}

Polymorphism

There are three important grammatical foundations in polymorphism: upward transformation, dynamic binding, and rewriting. Indispensable~

1. Upward transformation

The reference of the parent class points to an object of the child class (it looks like the reference of the child class has been turned into a reference of the parent class). There are three kinds of timing: direct assignment, method parameter transfer, and method return. The following is an example for analysis.

Example① Direct assignment

class Animal{
    
}
class Cat extends Animal{
    
}
public class Pra {
    Animal animal=new Cat();  //直接赋值时发生向上转型
}

Example ② When the method is passed parameters

//Animal和Cat两个类和例①中的一样,就不再写了
//......
public class Pra {
    public static void main(String[] args) {
        func(new Cat());
    }

    public static void func(Animal animal) {  //传参时发生向上转型

    }
}

Note that the actual parameter passed when the func function is called is an instance of Cat, and the formal parameter is an Animal type.

Example ③When the method returns

public static Animal func() {
    return new Cat();  //方法返回时发生向上转型
}

The return value of the func function is of type Animal, and the return statement returns an instance of Cat

Note: The reference of the parent class can only access the properties and methods in the parent class, and cannot access the unique properties and methods of the subclass.

We can understand the reference as a low-profile pointer, which stores the address.

2. Dynamic binding

If the method contained in the parent class has a corresponding method with the same name and parameters in the subclass , it will be dynamically bound. It is up to the runtime to decide which method to call.

Generally, dynamic/static refers to compile time/run time, and has nothing to do with static.

Example

class Animal{
    public void eat(String food){
        System.out.println("小动物正在吃"+food);
    }
}
class Cat extends Animal{
    public void eat(String food){
        System.out.println("小猫正在吃"+food);
    }

}
public class Pra {
    public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat("小鱼干");
    }
}

operation result

analysis:

In our parent class Animal and subclass Cat, there is a method eat() with the same name and the same parameters. At this time, dynamic binding is involved. When the program is running, it depends on whether the animal points to an instance of the parent class or to a child. Instance of the class. Pointing to the instance of the parent version will execute the eat of the parent version, and pointing to the instance of the child version will execute the eat of the child version. Whether the animal reference points to an instance of the parent class or a subclass can only be determined at runtime.

3. Rewrite

In fact, rewriting is essentially the same thing as the above dynamic binding , but the perspective is different. Dynamic binding, we are from the perspective of the compiler and the JVM implementer , while the method rewriting is I am standing on the syntax of the Java level on the view. In other words, method rewriting is a rule on the grammatical level of Java, and dynamic binding is the underlying implementation of method rewriting this grammatical rule.

Overriding means that there are methods with the same name and the same parameters between the parent class and the child class. At this time, calling the method through the reference of the parent class will trigger the rewriting. At this time, the specific version of the method to be executed depends on the dynamic binding rules. Decided.

In the code, we have to tell the compiler that the method of the current subclass is to override the method of the parent class, so that the compiler can better check and verify the work. Just add the annotation @Override .

4. Examples of polymorphism

For example, the new product should be compatible with the functions of the old version, and new functions should be added on this basis. Especially when using classes developed by others, this idea is more common.

Let us illustrate with an example.

① Parent Shape

public class Shape {
    public void draw(){

    }
}

②Subclass Circle

public class Circle extends Shape{
    @Override
    public void draw() {
        System.out.println("⚪");
    }
}

③Subclass Rect

public class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("□");
    }
}

④Subclass Flower

public class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

⑤Main

public class Main {
    public static void main(String[] args) {
//        Shape shape1=new Circle();
//        Shape shape2=new Rect();
//        Shape shape3=new Flower();
//        drawShape(shape1);
//        drawShape(shape2);
//        drawShape(shape3);
        Shape[] shapes={new Circle(),new Rect(),new Flower()};
        for(Shape x:shapes){
            drawShape(x);
        }
    }
    public static void drawShape(Shape shape){
        shape.draw();
    }
}

operation result

Analysis: Polymorphism is a way of thinking in program design. The specific grammar reflects: upward transformation, method rewriting, and dynamic binding. The intuitive understanding of polymorphism, " a reference corresponds to multiple forms (different types of instances)".

Shape[] shapes={new Circle()...} here embodies the upward transformation in polymorphism . In the drawShape() method, shape.draw() embodies the dynamic binding . Whether the draw method in the Shape or the draw method in the subclass is called is determined at runtime. In Circle, Rect, Flower, there is a method with the same name and the same parameter (draw) as the method in the parent class, which reflects the method rewriting .

The person who implements the drawShape method and the person who implements Shape, Cicle... may not be the same person. If this drawShape method is to be implemented by ourselves, the function is to call the draw method of shape, then directly write shape.draw() in the method; it does not matter whether the shape points to the circle type, flower No need to judge the type. If the shape points to an instance of a circle, call the draw of the circle, and call the draw of the flower when it points to the flower. I don't need to think about these, I just need to write one sentence.

The benefits of polymorphism:

  • The first benefit: the design idea of ​​polymorphism is essentially a step closer to "encapsulation" . The purpose of encapsulation is to allow the user of the class to use it without knowing the implementation details of the class, but the user still needs to know what type the class is; if polymorphism is used, the user of the class at this time does not only need to know For the implementation details of the class, there is no need to know the specific type of the class, just know that the class has a draw method. At this time, the user of the class knows less information and costs less to use.
  • The second benefit: easy to expand . In the future, if new subcategories need to be added, the impact on the users of the subcategories will be minimal.
  • The third benefit: eliminate some branch statements and reduce the cyclomatic complexity of the program.

5. Downward transformation

Convert the reference of the parent class to the reference of the subclass.

1) Parent category: Animal, subcategories: Cat, Bird. Here is an example:

Example ①

Animal animal=new Cat();
Cat cat=(Cat)animal;  //向下转型

Analysis: The above code is correct. Downcasting must ensure that the animal pointed to is an instance of the Cat type before the conversion can be performed, otherwise the conversion may fail.

Example ②

Animal animal2=new Bird();
Cat cat2=(Cat)animal2; //这是无效的

Analysis: The above code transformation is invalid. Down-casting is restricted and cannot be turned at will. In fact, it is equivalent to the reverse process of up-casting. The reference to the parent class obtained through up-casting is used to restore the original type with the help of down-casting.

However, here, we first convert the reference of the Bird instance to the animal2 reference of the Animal parent class, and then try to convert the animal to the Cat type. Although the compilation can pass, it is invalid.

Example ③

Animal animal3=new Animal();
Cat cat3=(Cat)animal3;  //这是无效的

Analysis: Although the compilation can pass, it is invalid.

2) Application scenarios of downward transformation (such as in the database):

Some methods only exist in the child class, but do not exist in the parent class . At this time, the method of the corresponding subclass cannot be executed using polymorphism, and the reference of the parent class must be converted back to the reference of the subclass (downcast), and then the corresponding method can be called.

Before downcasting, you can first determine whether the reference of the current parent class points to the subclass, if not, no downcasting is performed. Use instanceof (function: comparison type) to judge, so as to avoid the above example ②example ③invalid situation~

class Shape {
    public void draw(){

    }
}

class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape=new Flower();
        if(shape instanceof Flower){  //instanceof判断shape所指向的和Flower是不是同类型
            Flower flower=(Flower)shape;
            flower.draw();
        }
    }
    public static void drawShape(Shape shape){
        shape.draw();
    }
}

operation result

analysis:

instanceof can determine whether a reference is an instance of a certain class. If it is, it returns true. At this time, it is safer to perform down-casting~


After writing it for a long time, I finally finished it, but I feel that the writing is not in place, and I have to correct it slowly. Welcome everyone to give advice~~~

 

Guess you like

Origin blog.csdn.net/weixin_43939602/article/details/112987258