catalogue
4. Implement multiple interfaces
5. Inheritance between interfaces
7.Clonable interface and deep copy
8. Differences between interface abstraction and class abstraction
1, Abstract class
1. Concept
Print graphics
class Shape{ public void draw(){ System.out.println("Shape::draw()"); } } class Rect extends Shape{ @Override public void draw(){ System.out.println("♦"); } } class Flower extends Shape{ @Override public void draw(){ System.out.println("❀"); } } public class Test{ public static void drawMap(Shape shape){ shape.draw();//Dynamic binding } public static void main(String[] args){ Shape shape1 = new Rect();//Upward transformation Shape shape2 = new Flower();//Upward transformation drawMap(shape1); drawMap(shape2); } }
2. Grammar rules
abstract class Shape { abstract public void draw(); }
abstract class Shape{ public abstract void draw(); } class Rect extends Shape{ @Override public void draw(){ System.out.println("♦"); } } class Flower extends Shape{ @Override public void draw(){ System.out.println("❀"); } } public class Test{ public static void drawMap(Shape shape){ shape.draw();//Dynamic binding } public static void main(String[] args){ Shape shape1 = new Rect();//Upward transformation Shape shape2 = new Flower();//Upward transformation drawMap(shape1); drawMap(shape2); } }
3. Some precautions
(1) Abstract classes cannot be instantiated. Therefore, abstract classes can only be inherited
(2) Abstractions can also contain the same members and methods as ordinary classes
abstract class Shape{ public int a; public void func(){ System.out.println("Common test methods!"); } public abstract void draw();//Abstract method }
(3) If an ordinary class inherits an abstract class, all abstract methods of the abstract class need to be overridden in the ordinary class
abstract class Shape{ public int a; public void func(){ System.out.println("Common test methods!"); } public abstract void draw();//Abstract method } class Rect extends Shape{ @Override public void draw(){ System.out.println("♦"); } }
(4) If an abstract class a inherits an abstract class B, the abstract class A may not implement the abstract method of the abstract parent class B; However, after a is inherited by an ordinary class again, the abstract methods in the two abstract classes a and B must be overridden (they must always be returned if they are mixed)
abstract class Shape{ public int a; public void func(){ System.out.println("Common test methods!"); } public abstract void draw();//Abstract method } abstract class A extends Shape{ public abstract void funcA(); } class B extends A{ @Override public void funcA(){ ...... } @Override public abstract void draw(){ ...... } }
(5) Abstract classes cannot be modified by final, and abstract methods cannot be modified by final (the function of final is to restrict classes from being inherited, but the function of abstract classes is to be inherited. The two contradict each other)
(6) Abstract methods cannot be private
4. Role of abstract classes
2, Interface
1. Elaboration
2. Grammar rules
interface IShape { //public abstract void draw(); Full format void draw();//Simplified format } class Cycle implements IShape { @Override public void draw() { System.out.println("○"); } } public class Test { public static void main(String[] args) { IShape shape = new Rect(); shape.draw(); } }
(1) Define an interface using interface
(2) The methods in the interface must be abstract methods, so abstract can be omitted;
(3) The method in the interface must be public, so public can be omitted
(4) Cycle uses implements to inherit the interface At this time, the meaning of expression is no longer "extension", but "implementation"
(5) There can be static methods in the interface
(6) The member variable in the interface is modified by public static final by default
(7) When a class implements an interface, it must rewrite the abstract methods in the interface
(8) When a class implements an interface and rewrites the method, the method must be preceded by public
interface IA{ int A = 10; void funcA();//public abstract } class AClass implements IA{ public void funcA(){//The access modifier of the subclass should be > = the parent class ....... } }
(9) Ordinary methods in the interface cannot have specific implementation. If they have to be implemented, they can only be modified by the keyword default
interface IShape{ public abstract void draw(); default public void func(){ System.ou.println("helloworld"); } }
(10) Interfaces cannot be instantiated alone
(11) When calling, you can also create an interface reference corresponding to an instance of a subclass
3. Some writing standards
4. Implement multiple interfaces
class Animal{ protected String name; public Animal(String name){ this.name = name; } } interface IFlying{ void flying(); } interface IRunning{ void running(); } class Duck extends Animal implements IFlying,IRunning{ public Duck(String name){ super(name); } @Override public void flying(){ System.out.println(this.name+" Flying!"); } @Override public void running(){ System.out.println(this.name+" Running!"); } } class Cat extends Animal implements IRunning { public Cat(String name) { super(name); } @Override public void running() { System.out.println(this.name + " Running"); } } public class TestDemo{ public static void runFunc(IRunning iRunning){ iRunning.running(); } public static void main(String[] args){ runFunc(new Duck("haha")); runFunc(new Cat("hehe")); } }
Compile and run the program, and the output is as follows:
haha is running
hehe is running
5. Inheritance between interfaces
As you can see from the above, the relationship between classes and between classes and interfaces is implemented. Interfaces and interfaces can use extensions to operate their relationships. Extensions here means "extension". An interface B extends the functions of another interface C through extensions. At this time, when a class D implements this interface B through implements, the rewritten method is not only the abstract method of B, but also the functions (Methods) it extends from the C interface
interface IA{ void funcA(); } interface IB extends IA{//At this time, the function of IA is also available here void funcB(); } class C implements IB{ @Override public void funcB(){ System.out.println("hello"); } @Override public void funcB(){ System.out.println("world"); } }
6. Interface usage examples
(1) Comparable interface
import java.util.Arrays; class Student implements Comparable<Student>{//Comparative students public int age; public String name; public double score; public Student(int age, String name, double score) { this.age = age; this.name = name; this.score = score; } //Unlike ordinary integers, two integers can be directly compared, and the size relationship is clear However, the size relationship between the two Student objects needs to be specified additionally. Let's let the Student class implement the Comparable interface and implement the compareTo method @Override public int compareTo(Student o) { /*if(this.age > o.age){//Whoever calls this method is this return 1; }else if(this.age == o.age){ return 0; }else{ return -1; }*/ //return this.age - o.age;// Sort from small to large //return o.age - this.age;// Comparison from large to small //Comparison score //return (int)(this.score - o.score); //Compare names return this.name.compareTo(o.name);//The comparison of reference types must rely on its comparable methods } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + ", score=" + score + '}'; } } public class Test { public static void main(String[] args) { Student[] students = new Student[3]; students[0] = new Student(12,"zhangsan",98.3); students[1] = new Student(6,"lisi",85.9); students[2] = new Student(16,"wangwu",60.8); System.out.println(Arrays.toString(students)); Arrays.sort(students);//The default sorting is from small to large. You can modify whether to sort in ascending or descending order only when you encounter a custom sorting type System.out.println(Arrays.toString(students)); } }
Note: for the sort method, each object of the array that needs to be passed in is "comparable", which requires the ability of compareTo By overriding the compareTo method, you can define comparison rules
One disadvantage of this interface is that it is very intrusive to classes. Once the code is written, it can't be changed easily
(2) Comparator interface (comparator)
import java.util.Arrays; import java.util.Comparator; class Student{//Comparative students public int age; public String name; public double score; public Student(int age, String name, double score) { this.age = age; this.name = name; this.score = score; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + ", score=" + score + '}'; } } class AgeComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { return o1.age - o2.age; } } class NameComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } } public class Test { public static void main(String[] args) { Student[] students = new Student[3]; students[0] = new Student(12,"zhangsan",98.3); students[1] = new Student(6,"lisi",85.9); students[2] = new Student(16,"wangwu",60.8); System.out.println(Arrays.toString(students)); //AgeComparator ageComparator = new AgeComparator(); NameComparator nameComparator = new NameComparator(); Arrays.sort(students,nameComparator);//The default sorting is from small to large. You can modify whether to sort in ascending or descending order only when you encounter a custom sorting type System.out.println(Arrays.toString(students)); } }
Comparator interface is flexible, and its intrusion into classes is very weak
But when we choose which interface to use, it depends on our business processing
7.Clonable interface and deep copy
s Person implements Cloneable{ public int age; public void eat(){ System.out.println("Eat!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class TestDemp { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.age = 99; Person person2 = (Person)person.clone();//Person inherits Object by default. In theory, it can call the cloning method, but it is also special. After calling the cloning method, you have to rewrite the cloning method System.out.println(person2); System.out.println("------------------"); person2.age = 100; System.out.println(person); System.out.println(person2); } }
Compile and run the code, and the output is as follows:
Judging from the code implementation, it is a deep copy, but we should know that deciding whether to make a deep copy or a shallow copy is not the purpose of the method, but the implementation of the code. Let's take a look at the memory distribution diagram of this code
Let's take another look at the code:
class Money{ public double m = 12.3; } class Person implements Cloneable{ public int age; public Money money = new Money(); public void eat(){ System.out.println("Eat!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class TestDemp { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person person2 = (Person)person.clone();//Person inherits Object by default. In theory, it can call the cloning method, but it is also special. After calling the cloning method, you have to rewrite the cloning method System.out.println(person.money.m); System.out.println(person2.money.m); System.out.println("------------------"); person2.money.m = 99.99; System.out.println(person.money.m); System.out.println(person2.money.m); } }
Compile and run the code, and the output is as follows:
From the implementation of this code, it is a shallow copy. Let's take a look at the memory distribution diagram of this Code:
So now we want to turn it into a deep copy. How do we achieve it? You only need to clone a copy of Money, as follows:
class Money implements Cloneable{ public double m = 12.3; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable{ public int age; public Money money = new Money(); public void eat(){ System.out.println("Eat!"); } @Override public String toString() { return "Person{" + "age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { //return super.clone(); //Equivalent to: //Person tmp = (Person)super.clone(); //return tmp; Person tmp = (Person)super.clone(); tmp.money = (Money) this.money.clone(); return tmp; } } public class TestDemp { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person person2 = (Person)person.clone(); System.out.println(person.money.m); System.out.println(person2.money.m); System.out.println("------------------"); person2.money.m = 99.99; System.out.println(person.money.m); System.out.println(person2.money.m); } }
Compile and run the code, and the output is as follows:
Let's take a look at the memory distribution diagram of this code
Summary: deciding whether to copy deep or shallow is not the purpose of the method, but the implementation of the code
8. Differences between interface abstraction and class abstraction
No | difference | abstract class | Interface |
1 | Structural composition | Ordinary class + abstract method | Abstract method + global variable |
2 | jurisdiction | Various permissions | public |
3 | Subclass use | Use the extends keyword to inherit abstract classes | Use the implements keyword to implement the interface |
4 | relationship | An abstract class can implement several interfaces | Interfaces cannot inherit abstract classes, but interfaces can inherit multiple parent interfaces using the extends keyword |
5 | Subclass restrictions | A subclass can only inherit one abstract class | A subclass can implement multiple interfaces |