【JavaSE】What is an abstract class? What are inner classes? and what do they do?

 In this article, we mainly study two knowledge points, which can solve the three problems raised by the title of the article.

 

Table of contents

1. Abstract class

1.1 Abstract class concept

1.2 Abstract class syntax

1.3 Abstract class features

1.4 The role of abstract classes

2. Inner class

2.1 Classification of inner classes

2.2 instance inner class

2.3 Static inner class

2.4 Anonymous inner class

2.5 Local Inner Classes


1. Abstract class

In the study of polymorphism, we have written such a piece of code:

class Shape {
    //属性....
    public void draw() {
        System.out.println("画图形!");
    }
}
class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("♦");
    }
}
class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("●");
    }
}
class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("▲");
    }
}

However, we will find that the draw() method in the parent class Shape seems to have never been used, can we not write the implementation part of draw() ? The answer is yes, the abstract class will come back to help us solve this problem.


1.1 Abstract class concept

In the object-oriented concept, all objects are described by classes, but conversely, not all classes are used to describe objects, if a class does not contain enough information to describe a specific object , such a class is an abstract class. for example:

illustrate:

  1. Rectangles, triangles, and circles are all graphics, so they should be in an inheritance relationship with the properties of the Shape class.
  2. Although the draw method also exists in the graphics graph Shape , because the Shape class is not a specific graphic, there is actually no way to implement the draw method inside it.
  3. Since the Shape class has no way to describe a specific graphic, its draw0 method cannot be implemented concretely, so the Shape class can be designed as an "abstract class".

In the example of printing graphics, we found that the draw method in the parent class Shape does not seem to have any actual work, and the main drawing graphics are done by the draw methods of various subclasses of Shape. Like this without actual work method, we can design it as an abstract method (abstract method), and the class containing the abstract method is called an abstract class (abstract class) .

1.2 Abstract class syntax

In Java , if a class is modified by abstract , it is called an abstract class, and the method modified by abstract in an abstract class is called an abstract method, and the abstract method does not need to give a specific implementation body.

For the shape class above , we can make the following modifications:

abstract class Shape {
    //属性....
    public abstract void draw();
}

Thus, shape is an abstract class.

// 抽象类:被abstract修饰的类
abstract class Shape {
    // 抽象方法:被abstract修饰的方法,没有方法体
    abstract public void draw();
    abstract void calcArea();
    // 抽象类也是类,也可以增加普通方法和属性
    public double getArea() {
        return area;
    }
    protected double area; // 面积
}

 Note: Abstract classes are also classes, which can contain ordinary methods and properties, and even construction methods

1.3 Abstract class features

1. Abstract classes cannot instantiate objects directly

2. Abstract methods cannot be private

3. Abstract methods cannot be modified by final and static , because abstract methods must be rewritten by subclasses

4. The abstract class must be inherited, and the subclass must rewrite the abstract method in the parent class after inheritance, otherwise the subclass is also an abstract class and must be modified with abstract

5. Abstract classes do not necessarily contain abstract methods, but classes with abstract methods must be abstract classes

6. There can be a construction method in the abstract class for the subclass to initialize the member variables of the parent class when creating an object

1.4 The role of abstract classes

The abstract class itself cannot be instantiated. If you want to use it, you can only create a subclass of the abstract class, and then let the subclass override the abstract method in the abstract class.

We may think that ordinary classes can also be inherited, and ordinary methods can also be overridden. Why do we have to use abstract classes and abstract methods?

Indeed. But the use of abstract classes is equivalent to an extra layer of compiler verification.

The scenario of using an abstract class is like the code above, the actual work should not be done by the parent class, but by the subclass. Then if you accidentally misuse it as a parent class at this time, you will not report an error if you use a normal class compiler. But if the parent class is an abstract class, an error will be prompted when instantiating, so we can find the problem as soon as possible.

The meaning of many grammars is to "prevent mistakes". For example, the final we have used is similar. The created variable is not modified by the user, is it equivalent to a constant? But adding final can be used when accidentally modifying , let the compiler remind us in time. It is very meaningful to make full use of the compiler's verification in actual development.

2. Inner class

When there is another part of a thing that needs a complete structure to describe, and the complete internal structure only provides services for external things, then it is best to use the inner class for the complete internal structure. In Java, a class can be defined inside another class or a method, the former is called an inner class, and the latter is called an outer class . Inner classes are also a form of encapsulation.

【Precautions】

1. Defined outside the curly braces of the class class name {}, even in a file, cannot be called an internal class

 2. The inner class and the outer class share the same java source file, but after compilation, the inner class will form a separate bytecode file

2.1 Classification of inner classes

Let's first look at where internal classes can be defined in a class

class OutClass {
    // 成员位置定义:未被static修饰 --->实例内部类
    public class InnerClass1 {
    }

    // 成员位置定义:被static修饰 ---> 静态内部类
    static class InnerClass2 {
    }

    public void method() {
        // 方法中也可以定义内部类 ---> 局部内部类:几乎不用
        class InnerClass5 {
        }
    }
}

 Depending on the location of the inner class definition, it can generally be divided into the following forms:

  1. Member inner class (ordinary inner class: member inner class not modified by static and static inner class: member inner class modified by static)
  2. Local inner classes (not to mention modifiers), anonymous inner classes

Note : In fact, internal classes are not used very much in daily development. When you look at the code in some libraries, you may encounter more. Anonymous internal classes are the most used in daily use.

2.2 instance inner class

That is, the member inner class that is not modified by static.

Definition of instance internal class member variables:

In the inner class of the instance, the member variable of static modification cannot be defined, unless the final modification is added:

When creating an instance internal class object, first create the external class object first, and then create the instance internal class object:

In the inner class of the instance, the outer class can be directly accessed: members modified by any access qualifier

If there are members with the same name in the outer class and the inner class of the instance, the inner class's own member will be accessed first

If you want to access members with the same name of the external class, you must: external class name.this. member name with the same name

class OuterClass {
    public int data1 = 1;
    public static int data2 = 2;
    private int data3 = 3;

    class InnerClass {
        public int data1 = 111;

        private int data4 = 4;
        public static final int data5 = 5;  //data5为常量
        protected int data6 = 6;

        public void test() {
            System.out.println("InnerClass::test()");
            System.out.println(data1);//优先访问的是内部类自己的data1
            System.out.println(OuterClass.this.data1); //访问外部类的data1
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }

    public void test() {
        System.out.println("OuterClass::test()");
        System.out.println(data1); //访问外部类成员变量
        System.out.println(data2);
        System.out.println(data3);
        //外部类方法访问内部类需要先创建内部类对象来访问
        InnerClass innerClass = new InnerClass();
        System.out.println(innerClass.data1);
        System.out.println(innerClass.data4);
        System.out.println(innerClass.data6);
    }
}

public class Test3 {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.test();
        outerClass.test();
    }
}

Output result:

 【Precautions】

1. Any member in the outer class can be directly accessed in the instance inner class method.

2. The location of the inner class of the instance is the same as that of the members of the outer class, so it is also restricted by access qualifiers such as public and private.

3. When accessing members with the same name in the method of the inner class of the instance, access to your own first. If you want to access members with the same name in the outer class, you must access: outer class name.this.member with the same name.

4. The inner class object of the instance must be created on the premise of the outer class object first.

5. The non-static method of the inner class of the instance contains a reference to the object of the outer class.

6. In the outer class, members in the inner class of the instance cannot be directly accessed. If you want to access, you must first create an object of the inner class.

2.3 Static inner class

The inner member class modified by static is called static inner class.

Creating a static inner class object does not require first creating an outer class object:

Static inner classes cannot directly access non-static member variables of outer classes:

class OuterClass {
    public int data1 = 1;
    public static int data2 = 2;
    private int data3 = 3;

    public static class InnerClass {
        public int data4 = 4;
        public static int data5 = 5;
        private int data6 = 6;
        void test() {
            System.out.println("InnerClass::test()");
            OuterClass outerClass = new OuterClass();
            //System.out.println(data1); //编译报错
            System.out.println(outerClass.data1);
            System.out.println(data2);
            //System.out.println(data3); //编译报错
            System.out.println(outerClass.data3);            
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}

【Precautions】

1. Only static members in the outer class can be accessed in the static inner class

2. When creating a static inner class object, there is no need to create an outer class object first

2.4 Anonymous inner class

Everyone who has studied interfaces knows that interfaces cannot instantiate objects:

 But we can create an anonymous inner class object through the interface:

 Output result:

2.5 Local Inner Classes

Defined in the method body or {} of the external class, this type of internal class can only be used in the position where it is defined, and is generally used very rarely. Here is a brief understanding of the syntax format.

public class Test3 {
    public static void func() {
        class AA {
            public int a = 1;
        }

        AA aa = new AA();
        System.out.println(aa.a);
    }

    public static void main(String[] args) {
        func();
    }
}

 

【Precautions】

1. Local inner classes can only be used inside the defined method body

2. Cannot be modified by public, static and other modifiers

3. The compiler also has its own independent bytecode file, naming format: external class name $number internal class name.class

4. Rarely used

Guess you like

Origin blog.csdn.net/m0_73648729/article/details/132149956