catalogue
Three principles of abstract class
Two built-in interfaces of JDK
①java.lang.Comparable comparison interface
②java. Lang. clonable clone interface
Deep and shallow copies of objects
The difference between abstract classes and interfaces
Abstract class
What is an abstract class? In real life, when we say "human", we cannot correspond to a specific person. Similarly, classes that cannot be mapped to specific objects such as "animal class" and "graphic class" are abstract classes.
Abstract class is a superset of ordinary class, which means that ordinary class has some abstract classes, but it has more abstract methods than ordinary class. These abstract methods can have one or more.
The meaning of its existence is to let subclasses override its abstract methods. Abstract classes and abstract methods are implemented using the abstract keyword:
At this time, Sharp class is an abstract class. You can see that its icon is different from ordinary classes.
Abstract method
Example:
public abstract void print();
The class of an abstract method must be an abstract class. An abstract method has only a method declaration and no method body {}
Pay attention to distinguish between the case where there is no method body and the case where the method body is empty
- public abstract void print();// There is no method body
- public abstract void print() {} / / the method body is empty. It is a normal method
Three principles of abstract class
1. Abstract classes cannot instantiate objects directly. For example, in the above sharp class, sharp # sharp = new # Sharp()// This is wrong
2. A subclass inherits an abstract class and must override all abstract methods in the abstract class (provided that the subclass is an ordinary class)
Triangle is an ordinary class. If we don't overwrite the method, we will report an error. At this time, we use the alt + enter shortcut key, click the first line, and then click ok to overwrite the abstract method of the parent class
However, when the subclass is still an abstract class, you can choose not to override the abstract method
3. final and abstract cannot be used at the same time;
private and abstract cannot be used at the same time
The greatest significance of the existence of abstract class is to be inherited, and it still satisfies the is a principle of inheritance relationship
abstract class Person
class Chinese extends Person √
class Dog extends Person × // Because Dog not is a Person
At the same time, abstract classes are still limited by single inheritance. At this time, we introduce interfaces to break these two limitations
Interface
Java uses the interface keyword to define the interface. In the interface, there are only global constants and abstract methods (before JDK). JDK8 extends the default method. Subclasses implement interfaces using implements
Generally, the naming of interfaces starts with the capital 'I' letter, and the subclass naming ends with Impl
Global constants:
public static final int NUM = 10;
Abstract method:
public abstract String msg( );
Interface usage principle
1. The interface has only public permissions and only global constants and abstract methods, so the keywords abstract, static, final and public can be omitted inside the interface
public interface IMassage { int NUM = 10;//Global constant String msg();//Abstract method }
2. There is no single inheritance restriction on interfaces. Subclasses can implement multiple parent interfaces at the same time, and multiple interfaces are separated by commas. At this point, the subclass must implement all the abstract methods in the parent class interface
public interface IMassage { int NUM = 10;//Global constant String msg();//Abstract method } interface INews{ void getNews(); } //Subclass public class MessageImpl implements IMassage,INews{ public String msg() { return null; } public void getNews() { } }
Interfaces can inherit multiple parent interfaces using extensions. In the following example, if A class wants to implement interface C, it must override all abstract methods in A, B and C
interface A{ void testA(); } interface B{ void testB(); } interface C extends A,B{ }
3. The interface still cannot instantiate the object directly and needs to be implemented through upward transformation
public class MessageImpl implements IMassage,INews{ public String msg() { return "hello JAVA"; } public void getNews() { System.out.println("hello n~"); } public static void main(String[] args) { IMassage m = new MessageImpl(); System.out.println(m.msg()); } } //Output: hello JAVA
m can only call msg method, not the method defined by INews interface class. It needs to be called by mutual conversion between parent classes
INews n = (INews)m; n.getNews(); //Output: hello n~
4. If subclasses want to inherit classes and implement interfaces, they should inherit first and then implement interfaces
public class D extends A implements X,Y{ }
Two built-in interfaces of JDK
java.lang.Comparable comparison interface
Introduction example: using sorting method to compare objects in Student class
public class Student { private String name; private int age; public Student(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "Student{" + "name=" + name+'\''+ ",age="+ age + '}'; } public static void main(String[] args) { Student s1 = new Student("Zhang San",18); Student s2 = new Student("Li Si",20); Student s3 = new Student("Wang Wu",30); Student[] students = {s3,s1,s2}; Arrays.sort(students); System.out.println(Arrays.toString(students)); } }
Operation results:The program reports an error because the Student class is a user-defined type. When using arrays When sort method is used to sort user-defined types, user-defined types need to implement Comparable to have Comparable ability
Therefore, we make the following changes to the above example:
public class Student implements Comparable<Student>{ private String name; private int age; public Student(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "Student{" + "name=" + name+'\''+ ",age="+ age + '}'; } @Override public int compareTo(Student o) { if (this.age == o.age){ return 0; }else if (this.age < o.age){ return -1; } return 1; } public static void main(String[] args) { Student s1 = new Student("Zhang San",18); Student s2 = new Student("Li Si",20); Student s3 = new Student("Wang Wu",30); Student[] students = {s3,s1,s2};//Put the array out of order Arrays.sort(students); System.out.println(Arrays.toString(students)); } } //Output result: [Student{name=Zhang San',age=18}, Student{name=Li Si',age=20}, Student{name=Wang Wu',age=30}]
You can see that the array is sorted in ascending order of age, which has achieved the expected effect. If you want to arrange in descending order by age, you only need to modify one and negative one in the compareTo method
To implement the Comparable interface, its compareTo method must be overridden. The number returned by this method:
- =0 means that the current object is equal to the target object o
- >0 means that the current object is equal to the target object o
- < 0 indicates that the current object is equal to the target object o
java. Lang. clonable clone interface
In a program, cloning refers to copying a new object, and the attribute value of the new object is copied from the old object
Cloneable interface is a tag interface without any abstract method. When a class implements the Cloneable interface, it means that the class has the ability of cloning. This ability is given by the JVM. You should know that opening up space on the heap and object creation are implemented by the JVM.
We need to override the clone method of the Object class. Click the up transformation icon to see the method provided by the Object
It can be seen that the clone method has no method body and is modified with the native keyword. It is called a local method. The clone method is not implemented in Java language, but in C + +. You should know that the JVM is implemented in C + +. Therefore, the local method means that Java calls the method with the same name in C + +. Here is only the method declaration, and the specific method implementation is in C + +. So although it has no method body, it is not an abstract method.
Here we can know a small knowledge point: a method without method body is not necessarily an abstract method
Code example:
public class Cat implements Cloneable{ private String name; @Override protected Cat clone() throws CloneNotSupportedException { return (Cat) super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { Cat c1 = new Cat(); c1.name = "Meow meow"; Cat c2 = c1.clone(); System.out.println(c1 == c2); System.out.println(c2.name); } }
Output result:
You can see that the output false indicates that c1 and c2 are not at the same address, that is, a new space is opened up for c2 on the heap and the value of c1 is copied to c2
Deep and shallow copies of objects
Let's start with an example:
class A{ int num; } public class B implements Cloneable{ A a = new A(); @Override protected B clone() throws CloneNotSupportedException { return (B)super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { B b1 = new B(); B b2 = b1.clone(); System.out.println(b1 == b2); System.out.println(b2.a.num); b1.a.num = 100; System.out.println(b2.a.num); } } Output: false 0 100
According to the results, we will see After the value of a is changed to 100, B2 A also changes, that is, B1 A and B2 A points to the same object
This is called shallow copy. The copied b1 object only copies b1 itself, but does not copy the a object contained inside At this time, the a reference contained in b1 and b2 still points to the same object At this time, if you modify one side, the other side will also change
We will modify the code as follows:
class A implements Cloneable{ int num; @Override protected A clone() throws CloneNotSupportedException { return (A)super.clone(); } } public class B implements Cloneable{ A a = new A(); @Override protected B clone() throws CloneNotSupportedException { B b = new B(); b.a = a.clone(); return b; } public static void main(String[] args) throws CloneNotSupportedException { B b1 = new B(); B b2 = b1.clone(); System.out.println(b1 == b2); System.out.println(b2.a.num); b1.a.num = 100; System.out.println(b2.a.num); } } result: false 0 0
We let class a also implement the clone interface. You can see b1 The modification of a has no effect on b2 a. It shows that the a objects contained in b1 and b2 are also different at this time. This kind of copy is called deep copy
In Java, there are two ways to implement deep copy: one is to implement clonable recursively, and the above example is recursive; The other is to copy through serialization (Serializable interface). These two methods are no longer commonly used. Now the implementation of deep copy is to convert the object into json string