Make writing a habit together! This is the sixth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.


⭐️ ⭐️

This article will introduce you to the basics of Java — composition, polymorphism and interfaces. Dear friends, long time no see. This article will detail polymorphism and interface, the last introduces the inheritance is the basis of reading this article, first reflex plate of the inheritance, for example, we might as well put the drawings into two categories, category has the generality, another kind has the characteristic, has inherited the characteristics of drawing has commonness of drawings, have a common drawings (class) called a parent class (base class, the class), A drawing (class) with features is called a subclass. The relationship between the two is that the subclass inherits the parent class. The object instantiated by the subclass is equivalent to one object of two drawing instances. Then, start the body!

📒 blog homepage: not seen flower smell blog homepage 🎉 welcome to pay attention to 🔎 like 👍 collect 🎉 🎉 message 📒 📆 Nuggets debut: 🌴 April 7, 2022 🌴 ✉️ Perseverance and hard work will be exchanged for poetry and distance! 💭 refer to books: 📚 “Java programming ideas”, 📚 “Java core technology” 💬 refer to online programming website: 📚 niuke.com SILVER force to deduct the code cloud of the blogger gitee, usually the program code written by the blogger are in it. Github of the blogger, the program code written by the ordinary blogger is in it. 🍭 author level is very limited, if you find mistakes, be sure to inform the author in time! Thank you, thank you!


Combination of 1.

In the relation of inheritance, the relation between a subclass (derived class) and its parent class (base class, superclass) is IS-A, for example, a bird (subclass) inherits an animal (superclass), so it can be said that a bird is an animal.

For the combination, is used in a new class of one or more classes, for example we will create a school class, we all know that the school teachers, students, and usually must be more than one, so the school will use in class students and teachers, that is to say, combination is hava relationship, also is the school there is a teacher and students.

class Student {
    public String name;
    public double score;
    public int age;
    public int classNo;

}
class Teacher {
    public String name;
    public int age;
    public int classNo;
    public String subject;

}

public class School {
    public Student[] stu;
    public Teacher[] tec;
}
Copy the code

2. Polymorphism

2.1 Upward Transformation

An upward transition requires an inheritance relationship between classes, using a parent class reference to point to a subclass object. This is called an upward transition.

For example, Bird inherits from Animal and uses a reference from Animal to a Bird object. In Java, we allow a reference from a Bird object to a Bird object. But remember that the parent reference can only access the parent’s member variables and methods (if the child does not override the parent method). This animal reference can only access the eat method, not the fly method of the Bird subclass.

class Animal {
    public String name;
    public int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(a) {
        System.out.println(this.name + "Eating!"); }}class Bird extends Animal{

    public Bird(String name, int age) {
        super(name, age);
    }
    public void fly(a) {
        System.out.println(this.name + "Flying!); }}public class UpClass {
    public static void main(String[] args) {
        Animal animal = new Bird("The bird".2); animal.eat(); }}Copy the code

⭐️ There are three common cases of upward transformation:

  1. Passes the address of the subclass object to the parent class reference.
  2. Passes the address of the subclass object as an argument to the parameter of the superclass type.
  3. In a method whose return value is a parent reference type, the address of the subclass object is used as the return value.
class Animal {
    public String name;
    public int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(a) {
        System.out.println(this.name + "Eating!"); }}class Bird extends Animal{

    public Bird(String name, int age) {
        super(name, age);
    }
    public void fly(a) {
        System.out.println(this.name + "Flying!); }}public class UpClass {
    public static void func1(Animal an) {
        an.eat();
    }
    public static Animal func2(a) {
        return new Bird("The bird".2);
    }
    public static void main(String[] args) {
        Animal animal1 = new Bird("The bird".2);
        animal1.eat();
        func1(new Bird("The bird".2)); Animal animal2 = func2(); animal2.eat(); }}Copy the code

2.2 Runtime binding

2.2.1 concept

Runtime binding, also known as dynamic binding, is a behavior that occurs while a program is running. Run-time binding occurs on the basis of an upward transition, when an override (override/overwrite) method of the same name as a subclass is invoked via a superclass reference. Why is it called runtime binding? Because method overrides occur while the program is running, if we look at a compiled disassembly containing overridden code, we will find that the compiled method calls the parent method.

class Animal {
    public String name;
    public int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(a) {
        System.out.println(this.name + "Eating!"); }}class Bird extends Animal{

    public Bird(String name, int age) {
        super(name, age);
    }
    public void fly(a) {
        System.out.println(this.name + "Flying!);
    }

    @Override
    public void eat(a) {
        System.out.println(this.age + this.name + "Eating slowly!"); }}class Cat extends Animal{
    public Cat(String name, int age) {
        super(name, age);
    }
    public void cute(a) {
        System.out.println(name + "Busy dress cute!");
    }

    @Override
    public void eat(a) {
        System.out.println(this.age + this.name + "Eating quietly!"); }}public class OverFunc {
    public static void main(String[] args) {
        Animal animal1 = new Bird("The bird".2);
        animal1.eat();
        Animal animal2 = new Cat("Cat".1); animal2.eat(); }}Copy the code

2.2.2 Rewrite method

Rewriting is also called overwrite, cover, just as its name implies is to use a method overrides/overwrite/rewrite a method, but not any two methods can rewrite, rewrite is required, like method overloading, have specific provisions, rewrite method is in the midst of a subclass, the method is in the parent class is rewriting method.

⭐️ method rewrite conditions:

  1. Same method name
  2. Parameter lists are the same (including the number and type of parameters)
  3. Return values of the same type (except covariant return types)

Covariant return types mean that the return type of a member function in a subclass need not be exactly the same as the return type of the overridden member function in the parent class, but can be a more “narrow” type. For example, a subclass has this relationship with the return value of a superclass type.

⭐️ method rewrite Note:

  1. Static modifier methods cannot be overridden.
  2. The final modifier method cannot be overridden.
  3. Methods with private permissions cannot be overridden.
  4. When a subclass overrides a parent class method, the access rights of the overridden method in the subclass must be greater than or equal to that of the overridden method in the parent class.

Now that we know how to rewrite a method, let’s see if that program actually overwrites at run time, as we said.

The result is that the subclass’s EAT is called, indicating that overwriting occurs while the program is running and that overwriting does not occur when the program is compiled.

2.3 Binding at compile time

That’s run-time binding, now compile-time binding, which is when a program overloads a method, which happens at compile time, unlike overrides that happen at run time. Let’s look at a disassembly of code with an overload.

public class Func {
    public static int add(int a, int b) {
        return a + b;
    }
    public static int add(int a, int b, int c) {
        return a + b + c;
    }
    public static int add(int a, int b, int c, int d) {
        return a + b + c +d;
    }
    public static void main(String[] args) {
        int x = add(1.2);
        int y = add(1.2.3);
        int z = add(1.2.3 ,4); System.out.println(x); System.out.println(y); System.out.println(z); }}Copy the code

⭐️ rules for method overloading (review) :

  1. Same method name.
  2. Different parameter lists (including parameter types and numbers).
  3. Return value is not required.

Compile-time binding, also known as static binding, is the behavior of a program at compile time.

⭐️ The difference between overwriting and overloading:

The difference between rewrite overloading
concept Same method name, same argument list, same return value (except covariant return type) If the method name is the same and the parameter list is different, the return value is not required
The scope of Inheritance relationship (parent-child relationship) A class
limit Overriding methods of subclasses have greater access rights than overridden methods of their parent classes. Access rights cannot be private, final, or static Overloading can also occur with final and static modifications without permission requirements

2.4 Downward Transformation

Downward transitions are rarely used and unsafe. A downward cast is a cast in which the value referenced by the subclass is equal to the value referenced by the parent class.

Or look at an old chestnut:

class Animal {
    public String name;
    public int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(a) {
        System.out.println(this.name + "Eating!"); }}class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }
    public void cute(a) {
        System.out.println(name + "Busy dress cute!");
    }

    @Override
    public void eat(a) {
        System.out.println(this.age + this.name + "Eating quietly!"); }}class Bird extends Animal {

    public Bird(String name, int age) {
        super(name, age);
    }
    public void fly(a) {
        System.out.println(this.name + "Flying!);
    }

    @Override
    public void eat(a) {
        System.out.println(this.age + this.name + "Eating slowly!"); }}Copy the code

If the type matches after the downward transformation:

public class Instancesof {
    public static void main(String[] args) {
        Animal animal = new Cat("Cat".1);
        Cat cat = (Cat)animal;// Downward transitioncat.eat(); }}Copy the code

Type mismatch after downward transformation:


public class Instancesof {
    public static void main(String[] args) {
        Animal animal = new Cat("Cat".1); Bird Bird = (Bird) animal; bird.eat(); }}Copy the code

Why is it unsafe? Because a parent class can have multiple subclasses, and downcasting can cause type mismatches. Therefore, in order to avoid the occurrence of such exceptions, when using downward transformation, we often need to judge whether the type matches first. Here, we can use the keyword instanceof to refer to the subclass after downward transformation whether the type matches.

public class Instancesof {
    public static void main(String[] args) {
        Animal animal = new Cat("Cat".1);
        if (animal instanceof Bird) {
            Bird bird = (Bird) animal;
            bird.eat();
        }
        if (animal instanceofCat) { Cat cat = (Cat)animal; cat.eat(); }}}Copy the code

2.5 polymorphic

2.5.1 Understanding polymorphism

Now that we understand the upward transition, we can try to understand polymorphism, but let’s not talk about polymorphism, because it’s very abstract, but let’s do an example. There are many shapes in our life, such as circle, square, diamond, pentagram, triangle and so on, using inheritance and rewrite method to achieve a class Shape output a variety of shapes.

You define Shape, create a draw method in this class, and then create other concrete graphics classes that inherit Shape.

public class Shape {
    public void draw(a) {
        System.out.println("I want to print a shape!"); }}class Circle extends Shape{
    @Override
    public void draw(a) {
        System.out.println("" "); }}class Triangle extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Delta"); }}class Rhombus extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Left"); }}class Flower extends Shape{
    @Override
    public void draw(a) {
        System.out.println("❀"); }}class Star extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Do"); }}class Square extends Shape{
    @Override
    public void draw(a) {
        System.out.println("□"); }}Copy the code

Method 1: Use an array of subclasses to store the subclass’s objects, then loop through the subclass’s Draw override method.

public class Test {
    public static void main(String[] args) {
        Flower flower = new Flower();
        Square square = new Square();
        Star star = new Star();
        Rhombus rhombus = new Rhombus();
        Circle circle = new Circle();
        Triangle triangle = new Triangle();

        Shape[] shapes = {flower, square, star, rhombus, circle, triangle};
        for(Shape shape :shapes) { shape.draw(); }}}Copy the code

Method 2: Create a method that takes Shape and calls draw.

public class Test2 {
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        Flower flower = new Flower();
        Square square = new Square();
        Star star = new Star();
        Rhombus rhombus = new Rhombus();
        Circle circle = new Circle();
        Triangle triangle = newTriangle(); drawMap(flower); drawMap(square); drawMap(star); drawMap(rhombus); drawMap(circle); drawMap(triangle); }}Copy the code

Using method 2 to output various shapes can be called polymorphic. When a class caller writes a drawMap method with a Shape parameter of type (parent class), the caller does not know or care inside the method which type (subclass) the current Shape reference refers to. The shape reference calling draw may behave differently (depending on the instance of Shape). This behavior is called polymorphism.

Polymorphism is a reference that can take on many different shapes. That’s polymorphism, and polymorphism can make you forget about the type of the object. For example, you don’t care which subclass shape refers to, it will perform different methods or behave differently depending on the subclass object.

2.5.2 Advantages of polymorphism

✨1. Reduce the cost of using a class by class callers. Encapsulation is the idea that the caller of a class does not need to know the implementation details of the class. Polymorphism allows the caller of a class to know that the object has a method without knowing what the type of the class is. Thus, polymorphism can be understood as a further step in encapsulation, making it even cheaper for class callers to use the class. ✨2. Reduce the “cyclomatic complexity” of programs and reduce the use of branch statements. If there were no polymorphism, the draw method would have to determine which class to call when printing different types of shapes, and would have to use a lot of if-else branches. Cyclomatic complexity is a way of describing the complexity of a piece of code, which is easier to understand if it is laid out, and more complex if it has many conditional branches or loops. Therefore, we can simply calculate the number of conditional and loop statements in a piece of code, and this number is called “cyclomatic complexity “. If the cyclomatic complexity of a method is too high, you need to consider refactoring. In general, companies require a cyclomatic complexity of less than 10.

3. An abstract class

3.1 the abstract

In the previous implementation of polymorphisms when the parent class Shape draw method, are not called at runtime, because they are overwritten, calling the subclass draw method, so the parent class draw method is not necessary to have a concrete implementation. However, there is no C declaration in Java. If you declare methods in the form of C, you will get an error in Java.

An abstract method is a method that has no concrete implementation. It is modified by the keyword abstract. The purpose of an abstract method is to be overridden. To put it another way, if a class contains one or more abstract methods, the class must be qualified as abstract. That is, the class must be qualified with the keyword abstract.

In an abstract class you can define member variables, member methods, in terms of the properties and methods in the class, the difference is that an abstract class has abstract methods, everything else is the same. In addition, abstract classes are further abstractions of ordinary classes. Abstract classes cannot be instantiated as objects. The main purpose of abstract classes is to be inherited.

3.2 Characteristics of Abstract classes

  1. Classes that contain abstract methods are called abstract classes.
  2. Abstract methods are methods that have no concrete implementation, similar to declarations in C.
  3. Abstract classes cannot be instantiated as objects.
  4. The main purpose of abstract classes is to be inherited, and the main purpose of abstract methods is to be overridden.
  5. If a common class inherits an abstract class, that common class overrides all the abstract methods in the abstract class.
  6. If an abstract class B inherits from abstract class A and ordinary class C inherits from abstract class B, then ordinary class C overrides all the abstract methods in abstract class A and abstract class B.
  7. If an abstract class B inherits from another abstract class A, the abstract class B does not need to override the methods of abstract class A.
  8. An abstract class can contain the same member methods and member fields as a normal class.
  9. Abstract classes and methods cannot be modified by final.
abstract public class Shape {
    abstract public void draw(a);
}

class Circle extends Shape{
    @Override
    public void draw(a) {
        System.out.println("" "); }}class Triangle extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Delta"); }}class Rhombus extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Left"); }}class Flower extends Shape{
    @Override
    public void draw(a) {
        System.out.println("❀"); }}class Star extends Shape{
    @Override
    public void draw(a) {
        System.out.println("Do"); }}class Square extends Shape{
    @Override
    public void draw(a) {
        System.out.println("□"); }}Copy the code
public class Test2 {
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        Flower flower = new Flower();
        Square square = new Square();
        Star star = new Star();
        Rhombus rhombus = new Rhombus();
        Circle circle = new Circle();
        Triangle triangle = newTriangle(); drawMap(flower); drawMap(square); drawMap(star); drawMap(rhombus); drawMap(circle); drawMap(triangle); }}Copy the code

4. The interface

4.1 Initial Interface

An interface is a further abstraction of an abstract class. To create an interface, use the keyword interface instead of the keyword class. Just like a class, you can use the public modifier before interface (which must be the same as the file name). Interfaces, like classes, cannot be protected private. The interface name usually starts with a capital I. Common methods in the interface cannot be implemented. If they must be implemented, use the default modifier.

public interface Shape {
    public void draw(a);
    default public void print(a) {
        System.out.println("I have to implement methods in the interface!");// public after default can be omitted}}Copy the code

4.2 Interface Features

  1. Further abstraction of interface is an abstract class, using keywords interfaceinterfaceinterface defines the interface, the interface can be public to modify or not be access to the key words.
  2. An interface cannot instantiate an object using new because it is extremely abstract.
  3. Normal methods in an interface cannot be implemented. If you do, use defaultDefaultDefault.
  4. Interfaces can have static methods.
  5. All abstract methods in an interface are public abstract by default, and all methods in an interface are public.
  6. Class can be done by keyword implementsimplementsimplements interface.
  7. A class can inherit a maximum of one class or abstract class, and can implement multiple interfaces at the same time. The class inheritance comes first, and the interface implementation comes second, separated by commas.
  8. When a common class implements an interface, it must override the abstraction of all sides of the interface and its extended interfaces.
  9. Member variables in the interface are public static finalPublic \ static\ finalPublic static final.
  10. Interfaces have extended relationships with each other. The keyword extendsexTendsextends is used to indicate the extended relationships.
  11. When a class implements an interface, the overriding method access must be PublicPublicPublic.

Graphical output using interfaces:

public interface Shape {
    public void draw(a);
    default public void print(a) {
        System.out.println("I have to implement methods in the interface!");// public after default can be omitted}}class Circle implements Shape {
    @Override
    public void draw(a) {
        System.out.println("" "); }}class Triangle implements Shape {
    @Override
    public void draw(a) {
        System.out.println("Delta"); }}class Rhombus implements Shape {
    @Override
    public void draw(a) {
        System.out.println("Left"); }}class Flower implements Shape {
    @Override
    public void draw(a) {
        System.out.println("❀"); }}class Star implements Shape {
    @Override
    public void draw(a) {
        System.out.println("Do"); }}class Square implements Shape {
    @Override
    public void draw(a) {
        System.out.println("□"); }}Copy the code
public class Test {
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        Flower flower = new Flower();
        Square square = new Square();
        Star star = new Star();
        Rhombus rhombus = new Rhombus();
        Circle circle = new Circle();
        Triangle triangle = newTriangle(); drawMap(flower); drawMap(square); drawMap(star); drawMap(rhombus); drawMap(circle); drawMap(triangle); }}Copy the code

Using interfaces to describe animal behavior:

public class Animal {
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(a) {
        System.out.println(this.name + "Eating."); }}interface IRun{
    void running(a);
}
interface ISwim{
    void swimming(a);
}
interface IFly{
    void flying(a);
}
interface ISkip{
    void skipping(a);
}
class Frog extends Animal implements ISkip.ISwim{
    public Frog(String name) {
        super(name);
    }
    @Override
    public void swimming(a) {
        System.out.println(name + "Good at breaststroke!");
    }
    @Override
    public void skipping(a) {
        System.out.println(name + "Jump up!); }}class Bird extends Animal implements IFly{
    public Bird(String name) {
        super(name);
    }

    @Override
    public void flying(a) {
        System.out.println(name + "Flying free!"); }}class Cat extends Animal implements IRun.ISkip{
    public Cat(String name) {
        super(name);
    }

    @Override
    public void running(a) {
        System.out.println(name + "Gallop!");
    }

    @Override
    public void skipping(a) {
        System.out.println(name + "Can jump too!); }}class Duck extends Animal implements ISwim.IRun{
    public Duck(String name) {
        super(name);
    }

    @Override
    public void running(a) {
        System.out.println(name + "And run hard!");
    }

    @Override
    public void swimming(a) {
        System.out.println(name + "Can swim too!"); }}Copy the code
public class TestDemo {
    public static void running(IRun iRun) {
        iRun.running();
    }
    public static void swimming(ISwim iSwim) {
        iSwim.swimming();
    }
    public static void skipping(ISkip iSkip) {
        iSkip.skipping();
    }
    public static void flying(IFly iFly) {
        iFly.flying();
    }
    public static void main(String[] args) {
        Bird bird = new Bird("The bird");
        Cat cat = new Cat("Kitty");
        Frog frog = new Frog("Little Frog");
        Duck duck = new Duck("Little duck"); flying(bird); running(cat); running(duck); skipping(frog); skipping(cat); swimming(frog); swimming(duck); }}Copy the code