[Core Java] 05 Java class design and characteristics

Class design and characteristics

Class design

Hide data

For the encapsulation of the class, when designing the class, you should avoid developing the data field directly. In order to ensure that developers do not depend on our underlying details, the data field should be hidden (because there is no guarantee that the data form will not change) and a stable interface should be provided.

When necessary, accessors and changers will be provided to protect the data.

public long getAge() {
    
    
    return this.age;
}
public void setAge(int age) {
    
    
    // 校验 age 是否和发
    if(/* condition */){
    
    
        this.age = age;
    }
}

bool:

public boolean isMale() {
    
    
    return te;
}

public void setMale(boolean male) {
    
    
    this.amle = male;
}

Reference type:

Returning a reference is equivalent to directly exposing the data. This should be avoided. We can return a copy.

public String getName() {
    
    
    return this.name.clone();
}

However, there Stringis no such concern as it Stringis immutable.

Factory method

When a class is sufficiently complex, using factory methods to construct instances may be a better solution.

For example, this class has multiple subclasses according to different functions. In this case, you can use factory methods and return new instances in polymorphic form.

unit test

Any class can have a mainmethod, and since any mainmethod can be used as the entry point of a Java program, we can conveniently perform unit tests.

For example, if we want to test class A, we should implement a mainmethod in class A and then java Arun the test.

Variable parameter method

Like a printffunction in C/C++ , enter any number of parameters.

In Java, you only need to use the following syntax:

void method(Object...args) {
    
    
    for(Object obj : args) {
    
    
        // ... obj
    }
}

From the perspective of the implementer, there is no difference from the behavior of Object...one Object[].

From the perspective of the caller, any number of parameters can be passed in.

Packaging

The packaging class is a basic type of packaging, and its instance is immutable (avoid passing by reference).

Starting from jdk9, the construction method of the packaging class is annotated as obsolete, and it is recommended to use the factory method of the packaging class.

It is rarely appropriate to use this constructor. The static factory is generally a better choice, as it is likely to yield significantly better space and time performance.

Factory method: (take Integeran example)

public static Integer valueOf(int i)
public static Integer valueOf(String s)
public static Integer valueOf(String s, int radix)

This factory method is also the default behavior of the compiler during autoboxing, for example:

list.add(3);

After compilation, it is equivalent to:

list.add(Integer.valueOf(3));

Automatic unboxing will implicitly call:

int intValue()

Automatic unboxing often occurs in arithmetic operations or assignments:

int n = list.get(i);

Is equivalent to:

int n = list.get(i).intValue();

At the same time, the packaging class is also used as a tool class, and tools related to the corresponding basic type are encapsulated as static methods.

static String toString(int i)
// 整数转换为字符串
static String toString(int i ,int radix)
// 整数转换为 radix 进制的字符串

static int parselnt(String s)
// 字符串转换为整数
static int parseInt(String s,int radix) 
// 字符串转换为 radix 进制的整数

Enumeration class

The enumeration class in Java is not the same as the enumeration type in C/C++. In Java, the enumeration class is a class.

Define an enumeration class by enumreplacing class:

enum State {
    
    
    OPEN, CLOSE
}

Note that enumeration classes are not allowed to be defined in local scope (in methods).

The general situation of using enumeration classes:

State flag = State.OPEN;

if(flag == State.CLOSE){
    
    
    // ...
}

How is this achieved?

The enumeration class implicitly inherits the Enumclass, and a private constructor is called when the class is initialized to construct all the public static finalinstances.

These instances are the enumeration constants we defined. These constants are all objects, so they have some methods:

String name()
String toString()
// 返回字符串表示
    
int ordinal()
// 返回该对象的声明序号

int compareTo(E o)
// 对比声明顺序
    
boolean equals(Object other)
// 可以使用 == 
    
Class<?> getDeclaringClass()
// 返回枚举类的 Class 实例,或其外部类的 Class 实例

In addition, as a class, the enumeration class allows us to override methods, define constructs and member functions.

For example, leave a description for each enum constant and allow the caller to get this description:

enum State  {
    
    
    OPEN("This instance means that the current state is open"),
    CLOSE("This instance means that the current state is off");
    String desc;
    private State(String aDesc){
    
    
        this.desc = aDesc;
    }
    public String getDesc() {
    
    
        return desc;
    }
};

In an example, we can also achieve polymorphism of instances of enumeration classes.

Under normal circumstances, the enumeration class:

enum State  {
    
    
    OPEN, CLOSE
};

His principle is similar:

class State extends Enum{
    
    
    public static final State OPEN;
    public static final State CLOSE;
    
    private State(String name, int i) {
    
    
        super(name, i);
    }
    
    // 通过类的静态初始化块,实例化出所有枚举类型实例
    static {
    
    
        OPEN = new State("OPEN", 0);
        CLOSE = new State("CLOSE", 1);
    }
}

For this part:

public static final State OPEN;
public static final State CLOSE;

They may be Statesubclasses, we can define an abstract method in State, and then let these enumeration members inherit Stateand implement the abstract method:

enum State  {
    
    
    OPEN{
    
    
        @Override
        String getDesc() {
    
    
            return "This instance means that the current state is open";
        }
    },
    CLOSE {
    
    
        @Override
        String getDesc() {
    
    
            return "This instance means that the current state is off";
        }
    };
    abstract String getDesc();
};

The principle of this piece of code is equivalent to:

class State extends Enum{
    
    
    public static final State OPEN;
    public static final State CLOSE;
    
    private State(String name, int i) {
    
    
        super(name, i);
    }
    
    abstract String getDesc();
    
    // 通过类的静态初始化块,实例化出所有枚举类型实例
    static {
    
    
        OPEN = new State("OPEN", 0){
    
    
            @Override
            String getDesc() {
    
    
                return "This instance means that the current state is open";
            }
    	};
        CLOSE = new State("CLOSE", 1){
    
    
            @Override
            String getDesc() {
    
    
                return "This instance means that the current state is off";
            }
    	};
    }
}

Guess you like

Origin blog.csdn.net/qq_16181837/article/details/112294864