4 things we have to say about Java inheritance

content

1. Inheritance must use the extends keyword

2. Non-private properties and methods in the parent class can be inherited by the subclass

3. Constructors cannot be inherited and can only be called through the super keyword

4. Calling the constructor does not create an object, but initializes the data

The way to create an object 1.new keyword + constructor

The way to create an object 2.classloader

Ways to create objects 3. Reflection


So good evening everyone, I am the main lecturer this evening, I am Rabbit Brother.
The three major features of Java are inheritance, encapsulation and polymorphism.
Today, let's talk about inheritance. Although inheritance is not necessarily asked in interviews in today's Java introspection, this knowledge point is the top priority of our usual code development.

Therefore, mastering Java inheritance is very necessary.

1. Inheritance must use the extends keyword

The extends keyword means that we can inherit a parent class, also called a superclass.
For example, I have a class A.

public class A {
    private String name = "A";
}

Create a new class B and inherit from class A

public class B extends A{
}

Then we say that class B is a subclass of class A. Java does not allow multiple inheritance, only single inheritance, but multiple inheritance is possible.

What is multi-level inheritance, that is, I am creating a new class C and inheriting class B

public class C extends B{
}

2. Non-private properties and methods in the parent class can be inherited by the subclass

The access rights we generally use are public, protected and private.

Class A has a private name that subclasses cannot access, but only by themselves.

verify

If we change to public

public class A {
    public String name = "A";
}

 No errors were reported, the verification was successful!

However, for the part we want to be inherited by subclasses, we can use protected , which means protected, allowing inheritance to subclasses.

If we set the name to protected, look at the B and C classes 

The same will not report an error. 

However, protected properties cannot be accessed in other packages. (reported wrong)

Demo.java

public class Demo {
    public static void main(String[] args) {
        String name = new A().name;
        System.out.println(name);
    }
}

 The above code will report an error, and at the same time, it cannot be accessed in subpackages of the same package of class A.

 

Can only be accessed within the same package, or within its own subclass.

If Demo is also a subclass of A

public class Demo extends A{

    public void show(){
        System.out.println(super.name);
    }
}

This is allowed, no error will be reported ( even if it is not in a package ), we can also access name in class B and class C, but we need to use the super keyword.

Let's circle back and conclude that non-private properties and methods in the parent class can be inherited by the subclass!

If it is not set to public, it will cause a lot of trouble, and other packages cannot be called! Therefore, the parent class is generally for us to inherit, not for you to call directly elsewhere.

3. Constructors cannot be inherited and can only be called through the super keyword

The constructor of the parent class cannot be inherited, but we can call it through the super keyword.

When we new a class B object, the constructor of class A will be called first.

When we new a class C object, the constructors of class A and class B will be called successively.

verify:

public class A {
    protected String name = "A";

    public A(){
        System.out.println("A");
    }
}
public class B extends A{

    public B(){
        System.out.println("B");
    }

}
public class C extends B{
    public C(){
        System.out.println("C");
    }
}

test

public class Demo {
    public static void main(String[] args) {
       new C();
    }
}

result

Similarly, the parent class constructor must be public or protected. If private is used, the subclass cannot use it.

Although the C class compiles without error, it must report an error when running.

If the superclass constructor does not declare a default, but declares a parameterized constructor, the subclass must use the super keyword to call the superclass's parameterized constructor.

public class A {
    protected String name = "A";

    protected A(String name){
        System.out.println("A");
        this.name = name;
    }
}

Type B error

You must manually use the super keyword to call the parameterized construction of the parent class, even if you are just pretending

public class B extends A{

    public B(){
        super(null);
        System.out.println("B");
    }

}

If class A has multiple constructors, but there is no default constructor explicitly declared

public class A {
    protected String name = "A";
    protected int price = 100;

    protected A(String name){
        System.out.println("A");
        this.name = name;
    }

    protected A(String name,int price){
        System.out.println("A");
        this.name = name;
        this.price = price;
    }
}

A subclass can simply super a construction of a superclass, but it must be there.

public class B extends A{

    public B(){
        super(null);
        System.out.println("B");
    }

}

That's okay too

public class B extends A{

    public B(){
        super(null,1);
        System.out.println("B");
    }

}

Depends on your specific situation.

4. Calling the constructor does not create an object, but initializes the data

We have given so many examples, it is not difficult to find that the function of the constructor is only to initialize the data.

And we create objects in the form of using the new keyword with the constructor, so we may mistakenly think that calling the constructor will create the object.

There are generally three ways to create objects:

The way to create an object 1.new keyword + constructor

A a = new A("A",100);

The way to create an object 2.classloader

DiskClassLoader dcl = new DiskClassLoader("D:\\idea-workspace\\j2se\\out\\production\\j2se\\com\\javaxbfs\\bean");
/** 找到对应的class * */
Class<?> aClass = dcl.findClass("com.javaxbfs.bean.A");
/** 获取构造函数 * */
Constructor<?> constructor = aClass.getConstructor(String.class);
/** 用构造函数创建对象 * */
Object o = constructor.newInstance("A");
Method show = aClass.getMethod("show");
show.invoke(o);

DiskClassLoader is our custom class loader to load additional classes on disk. The code for DiskClassLoader is attached at the end.

Ways to create objects 3. Reflection

In fact, the above example has already used reflection.

It can be seen that the constructor is only used to initialize data, and does not create a new object.

Moreover, the constructor in the current class can be called by this in other constructors , and in the subclass constructor, it can be invoked by the super keyword ( and can only appear in the subclass's constructor ). And, it must be the first line of the method .

Finally, let's talk about the benefits of inheritance. The biggest benefit is naturally code reuse , while the disadvantage is that it increases coupling .

Attach the code of DiskClassLoader:

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


public class DiskClassLoader extends ClassLoader {

    private String mLibPath;

    public DiskClassLoader(String path) {
        // TODO Auto-generated constructor stub
        mLibPath = path;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // TODO Auto-generated method stub

        String fileName = getFileName(name);

        File file = new File(mLibPath,fileName);

        try {
            FileInputStream is = new FileInputStream(file);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int len = 0;
            try {
                while ((len = is.read()) != -1) {
                    bos.write(len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] data = bos.toByteArray();
            is.close();
            bos.close();

            return defineClass(name,data,0,data.length);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return super.findClass(name);
    }

    //获取要加载 的class文件名
    private String getFileName(String name) {
        // TODO Auto-generated method stub
        int index = name.lastIndexOf('.');
        if(index == -1){
            return name+".class";
        }else{
            return name.substring(index+1)+".class";
        }
    }

}

Guess you like

Origin blog.csdn.net/weixin_39570751/article/details/123602133