This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

preface

When we need to write A new class B, we already have A written class A, and A basically covers our requirements. All we need to do is press CTRL + C to copy A. Then CTRL + V to get A(1).java, rename the new file to b.java, and finally, fill in the missing functionality in B.java. That’s probably how we’ve spent most of our development lives

The good news is that Java provides A way to reuse classes by inheritance. In the example above, if the declaration of class B is class B extends A, then B has access to all of A’s fields and methods by default, as if it had written one of its own. Those methods in A must be declared public or protected, or package access, and A and B are in the same package directory.

class A{
  public void f(a){
    // do something
  };
}
class B extends A{
  public void g(a);
}
new B().f();	// use f() from A
new B().g();	// use g() by self
Copy the code

limit

In Java, each class can inherit only one class; Java.lang.object is inherited by default if the class is not specified

Using inheritance, a semantic description is xx is A YY, such as Trangle is a Shape, Dog is an Animal, Fish is Food. If there is no such relationship of IS A, it is suggested to use combination to replace inheritance

Another consideration is that we need to write entity classes that have common behavior, or common members, and by inheritance, we can omit this common code and actually have this functionality. As an added bonus, we can even introduce generics if we are writing common methods, such as public

void func(T T){}, which are qualified generics that allow us to use methods, parameters, and so on in the parent class of POJO

rewrite

When we use inheritance and find that some functionality in the parent class does not meet the new requirements, we need to upgrade the method or rewrite it more completely

class A{
	public void f(a){
    // do something
    System.out.print("A.f()")}; }class B extends A{
  @Overrid
  public void f(a){
    // do otherthings
    System.out.print("B.f()")
    super.f(); // If you need to call f() of the parent class, you can use a form like super.xx()
  }
  public void g(a);
}
Copy the code

In this example code block, we use the @override annotation to indicate that the current method overrides the corresponding method in the parent class. If the method does not exist in the parent class, an error message will be sent to prevent us from overwriting a method that does not exist in the parent class

If the purpose of our override method is to enhance the function of the corresponding method in the parent class, then we can perform XXX () in the parent class in a similar way to a method call through super.xxx().

And overload

rewrite

The emphasis is on subclasses overwriting corresponding methods in their parent classes

overloading

In the same class, use the same method name, but their argument lists are different so that the JVM can locate which method you are actually calling

Or, within the same class, the method name + argument list is unique

// An indication of method overload
class C{
  void f(a){};
  void f(int a, String b){}
  void f(String b, int a){}}Copy the code

Reload “trap”

The concept of overloading applies not only to methods but also to constructors. Read the next section of code carefully

class D{
  D(int a, String b){}
  D(Strgin b, int a){}
  static createInstanceForA(int a, String b){}
  static createInstanceForB(Strgin b, int a){}}Copy the code

When initializing class D, we only need to pass in two parameters, however, in the process of initialization, we need to do different operations, at that time, can do is to adjust the parameters of the order, by overloading acquires a new use of the constructor, but a very deadly problems in the operation, the semantic is not obvious, Others don’t know which constructor to actually call because their input types are exactly the same, just in different order. Of course, we can kindly provide comments (one of the worst things programmers can do: write comments for others).

To solve this problem, it is recommended to use the static factory idea to create an instance, provide a detailed description name for this method, the user knows the meaning of the specific operation is the latter two static methods, more friendly, right

Subclass initialization details

class A{
  A(int a){}
  A(){};
}
class B extends A{
  B(int a){
    // A(); // If no specification is displayed, the no-argument constructor in the parent class is called by default
    // do
  }
  B(){
  	A(1);	// We can also call the required A constructor manually
  	// do}}Copy the code

For cases where the parent constructor needs to be called manually:

  1. No parameterless constructor exists in the parent class
  2. We don’t want to default to the parent class’s no-argument constructor

This call operation must be written on the first line of the subclass constructor