abstract class
What is an abstract class?
Common class code example:
class Shape {//At this time, the methods in this Shape class have no specific implementation public void draw(){//If a method has no concrete implementation, the method can be an abstract method. } }
1. Abstract method: if a method is modified by abstract, it is an abstract method. Abstract methods can have no concrete implementation. You can end directly with a semicolon.
2. Classes containing abstract methods are called abstract classes. This class needs to be decorated with the keyword abstract.
Abstract class code example:
abstract class Shape {//Abstract class Shape public abstract void draw();//At this point, you can add an abstract keyword to the draw method. If a method is modified by abstract, it is called an abstract method }
In other words, an abstract class must contain abstract methods. Of course, it is OK not to include them. However, if a method in a class is an abstract method, the class must declare it as an abstract class.
Points to note about abstract classes
1. Abstract classes cannot be instantiated. Ordinary classes can instantiate an object, but abstract classes cannot instantiate an object, so shape = new shape();
Code example:
abstract class Shape {//Abstract class Shape public abstract void draw();//At this point, you can add an abstract keyword to the draw method. If a method is modified by abstract, it is called an abstract method } public class TestDemo1 { public static void main(String[] args) { Shape shape=new Shape();//error: abstract classes cannot be instantiated } }
2. There are not many differences between abstract classes (data members in classes) and ordinary classes. The only difference is that ordinary classes can be instantiated and abstract classes cannot be instantiated.
Code example:
abstract class Shape {//Abstract class Shape public abstract void draw();//Abstract method public int age;//Member properties private int name; public void func(){//Member method } }
What is the role of abstract classes?
3. The greatest significance of abstract classes is to be inherited.
4. If a class inherits an abstract class, the class must override the abstract method in the abstract class. If not, an error will be reported.
Code example:
abstract class Shape {//Abstract class Shape public abstract void draw();//Abstract method } class Cycle extends Shape {//The ordinary class Cycle inherits the abstract class Shape @Override //Override means rewriting, @ override is called annotation. Adding annotation to a method indicates that the method can be rewritten, //If a class inherits an abstract class, the class must override the abstract method in the abstract class. If it does not override, an error will be reported. public void draw(){//Rewrite of implementation method System.out.println("Draw one○"); } } class React extends Shape {//The ordinary class React inherits the abstract class Shape @Override //Rewrite shortcut key: ctrl+O or alt+insert; public void draw() {//Rewrite of implementation method System.out.println("Draw one♦"); } } class Quert extends Shape { @Override public void draw() { System.out.println("Draw one□"); } } class Flower extends Shape{ @Override public void draw() { System.out.println("Draw a flower❀"); } }
5. If you don't want to rewrite the abstract method in the abstract class, you can add abstract before the class that inherits the abstract class to make it become an abstract class. At this time, it becomes an abstract class and inherits the abstract class. However, if a class wants to inherit from an abstract class, it still needs to override the inheritance method in the abstract class, otherwise the class will report an error.
(that is, when abstract class A inherits abstract class B, A may not override the method in B, but once A is inherited again, it must override the abstract method.)
Code example:
abstract class Shape {//Abstract class Shape public abstract void draw();//Abstract method } abstract class React extends Shape {//Abstract class React inherits abstract class Shape } class Flower extends React{//Ordinary class inherits abstract class React @Override//Override abstract methods public void draw() { System.out.println("Draw a flower❀"); }
6. The reason why classes and methods are declared abstract is to be inherited and rewritten. Therefore, abstract classes or abstract methods must not be modified by final and private, because once modified, abstract methods cannot be rewritten.
7. Although the Shape class cannot be instantiated, it can still undergo upward transformation, polymorphism and runtime binding.
abstract class Shape {//At this time, the methods in this Shape class have no specific implementation public abstract void draw();//If a method has no concrete implementation, the method can be an abstract method. } class Cycle extends Shape {//Cycle inherits the abstract class Shape @Override //Override means rewriting, @ override is called annotation. Adding annotation to a method indicates that the method can be rewritten, //If a class inherits an abstract class, the class must override the abstract method in the abstract class. If it does not override, an error will be reported. public void draw() {//Rewrite of implementation method System.out.println("Draw one○"); } } class React extends Shape {//React inherits the abstract class Shape @Override public void draw() { System.out.println("Draw one♦"); } } class Flower extends React { @Override public void draw() { System.out.println("Draw a flower❀"); } class Quert extends Shape { @Override public void draw() { System.out.println("Draw one□"); } } } public class TestDemo1 { public static void drawMap(Shape shape) { shape.draw(); } public static void main(String[] args) { //Shape shape=new Shape();// Abstract classes cannot be instantiated //Although the Shape class cannot be instantiated, it can still undergo upward transformation, polymorphism and runtime binding Shape shape1 = new Cycle(); Shape shape2 = new React(); Shape shape3 = new Flower(); drawMap(shape1); drawMap(shape2); drawMap(shape3); } }
Print results:
Interview questions:
What is the difference between abstract classes and ordinary classes?
A: there are not many differences between data members in abstract classes and ordinary classes. The only difference is that ordinary classes can be instantiated and abstract classes cannot be instantiated
What is the difference between abstract classes and interfaces?
A: to answer this question, we have to learn what is an interface.
Interface
What is an interface?
An interface is a further step of an abstract class. An abstract class can also contain non abstract methods and fields. While the methods contained in an interface are abstract methods, and fields can only contain static constants.
Code example of interface:
interface IShape {//When we create an interface, the name of the interface usually starts with the capital letter I void draw(); //The methods in the interface must be abstract methods, so abstract can be omitted //The methods in the interface must be public, so public can be omitted } class Cycle implements IShape {//Cycle uses implements to inherit the interface. At this time, the meaning expressed is no longer "extension", but "implementation" @Override public void draw() { System.out.println("○"); } } public class TestDemo { public static void main(String[] args) { IShape shape = new Cycle();//When calling, you can also create an interface reference corresponding to an instance of a subclass // shape: interface reference, corresponding to new Cycle(): subclass instance shape.draw(); } }
rule of grammar:
-
Define an interface using interface
-
The methods in the interface must be abstract methods, so abstract can be omitted
-
The methods in the interface must be public, so public can be omitted
-
Cycle uses implements to inherit the interface. At this time, the meaning expressed is no longer "extension", but "implementation"
-
When calling, you can also create an interface reference corresponding to an instance of a subclass
-
Interfaces cannot be instantiated alone
The difference between extensions and implementations
Extension refers to the further expansion of functions when certain functions already exist
Implementation means that there is nothing at present and needs to be constructed from scratch
Eight considerations for implementing interfaces
1. The methods in the interface are abstract methods.
2. In fact, there can be specific implementation methods, which are modified by default. (added in JDK 1.8), but it is not used in general.
3. The member variables defined in the interface are constants by default, while those in abstract classes and ordinary classes are not constants by default, unless they are added with a final.
interface Shape{//Shape is an interface public static final int a=10;//The member variable defined in the interface is a constant by default } public class TestInterFace { }
4. In an abstract class, any type of member variable can be defined, but the member variable defined in the interface must be modified by public static final, and for fields, the interface can only contain static constants (final static)
The default method is public abstract. If it is written as private or protected, an error will be reported.
In a word, the default member variable in the interface is public static final, and the member method is public abstract.
interface Shape{//Shape is an interface public abstract void draw();//Abstract method public static final int num=10;//The member variables (fields) defined in the interface are static constants by default //The default member variable in the interface is public static final, and the member method is public abstract, //So it can also be written like this. int num=10; void draw(); } public class TestInterFace { }
The public, static and final keywords can be omitted. The omitted num still represents the public static constant
Tips:
1. When we create an interface, the name of the interface generally starts with the capital letter I
2. The naming of the interface generally uses the word of "adjective"
3. Alibaba code specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise
5. The interface cannot be instantiated separately. If you write this, you will report an error shape = new shape();
You can think of it this way. Interfaces are more abstract than abstract classes. Abstract classes can't be instantiated. Of course, interfaces can't.
6. The relationship between interfaces and classes can't be extended. Instead, implement should be used.
Interface is the same as inheritance. Once a class implements the interface Shape, it must override the methods in the interface.
7. The interface appears to solve the problem of Java single inheritance. (detailed explanation will be given later)
Because Java can only inherit one class and cannot inherit multiple classes, it is single inheritance. With an interface, you can solve the problem of Java single inheritance and realize the ability to inherit multiple classes.
8. As long as this class implements the interface, it can be transformed upward.
Interfaces can also be transformed upward. The premise is to ensure that this class implements the interface before assigning an object to the interface type.
Code example:
interface Shape {//Shape is an interface void draw(); class Cycle implements Shape {//Cycle implements the Shape interface //The relationship between interfaces and classes can't be extended. Instead, you should use implements. Once a class implements the interface Shape, you must override the methods in the interface @Override //Override means rewriting, @ override is called annotation. Adding annotation to a method indicates that the method can be rewritten, //If a class implements an interface, the class must rewrite the abstract method in the interface. If it does not rewrite, an error will be reported. public void draw() {//Rewrite of implementation method System.out.println("Draw one○"); } } class React implements Shape {//React implementation interface Shape @Override public void draw() { System.out.println("Draw one♦"); } } class Flower extends React {//Flowe inherits React @Override public void draw() { System.out.println("Draw a flower❀"); } } class Quert implements Shape {//Quert implements the Shape interface @Override public void draw() { System.out.println("Draw one□"); } } public class TestInterFace { public static void drawMap(Shape shape) { shape.draw();//Occurrence polymorphism } public static void main(String[] args) { Shape shape1 = new Cycle();//Interfaces can also undergo upward transformation, provided that an object is assigned to an interface type //Make sure that this class implements this interface. Shape shape2 = new React(); Shape shape3=new Quert(); Shape shape4=new Flower(); drawMap(shape1);//Upward transformation drawMap(shape2); drawMap(shape3); drawMap(shape4); } } }
Print results:
Implement multiple interfaces
Sometimes we need to make a class inherit from multiple parent classes at the same time. This is realized by multiple inheritance in some programming languages
However, only single inheritance is supported in Java, and a class can only extend one parent class. However, multiple interfaces can be implemented at the same time, and the similar effect of multiple inheritance can be achieved
Now we represent a group of animals by classes
class Animal{ protected String name; public Animal(String name){//Provides a constructor with one parameter. this.name=name; } }
In addition, we provide another set of interfaces, which respectively mean "can fly", "can run" and "can swim"
interface IFlying{//Provide an interface, and the name of the interface is generally dominated by verbs void fly();//Provide abstract methods } interface IRunning{ void run(); } interface ISwimming{ void swim(); }
Next, we create several specific animals
Cats can run,
Fish can swim
Frogs can run and swim (amphibians)
"Mandarin ducks" inhabit water, land and air.
class Cat extends Animal implements IRunning{//The cat inherits from Animal and implements the IRunning interface, because the cat is an Animal and has the function of running public Cat(String name){//Because Animal has a constructor, you need to provide a constructor with a parameter super(name); } public void run(){//When implementing the IRunning interface, you need to rewrite the run method of IRunning. System.out.println(this.name+"Running happily"); } } class Fish extends Animal implements ISwimming{//Fish inherits from Animal and implements the ISwimming interface, because fish is an Animal and has the function of swimming public Fish(String name){//Provides a constructor with one parameter super(name); } public void swim(){ System.out.println(this.name+"Swimming happily"); } } class Frog extends Animal implements IRunning,ISwimming{//Implementing multiple interfaces solves the problem of multiple inheritance. It's ok to implement whatever you want public Frog(String name){//Because Animal has a constructor, you need to provide a constructor with a parameter super(name); } //ctrl+O: override the run method of IRunning and the swim method of ISwimming @Override public void run() { System.out.println(this.name+"Running!!"); } @Override public void swim() { System.out.println(this.name+"Swimming!!"); } } class YuanYang extends Animal implements IRunning, ISwimming, IFlying { public YuanYang(String name) { super(name); } @Override public void fly() { System.out.println(this.name + "Flying with wings"); } @Override public void run() { System.out.println(this.name + "He is running on two legs"); } @Override public void swim() { System.out.println(this.name + "Floating on the water"); } } //From the way of implementing multiple interfaces, it can be found that it is inappropriate to write run methods, swim methods and fly methods in Animal. If they are written in Animal, multiple different classes need to be implemented, because not every Animal can these functions, so they should be written into the interface. After inheriting Animal, it is ok to implement whatever interface you want directly.
The above code shows the most common usage in Java object - oriented programming: a class inherits a parent class and implements multiple interfaces at the same time
The meaning of inheritance expression is is - a semantics, while the meaning of interface expression is xxx, which is mainly an abstraction of methods
A cat is an animal that can run
Frog is also an animal. It can run and swim
Mandarin duck is also an animal. It can run, swim and fly
What are the benefits of this design? Always keep the benefits of polymorphism in mind and let the program forget the type. With an interface, the user of a class does not have to focus on the specific type, but only on whether a class has some ability
For example:
class Robot implements IRunning{//Using the interface, no matter what class it is, as long as it can run, it can realize the function of running @Override public void run() { System.out.println("I'm a robot and I can run!"); } } public class TestMoreExtends { public static void main(String[] args) { IRunning iRunning=new Robot(); iRunning.run(); } }
Print results:
Code example of forgetting type and implementing polymorphism (inheritance):
class Robot implements IRunning{//Using the interface, no matter what class it is, as long as it can run, it can realize the function of running @Override public void run() { System.out.println("I'm a robot and I can run!"); } } public class TestMoreExtends { //Forget the type, implement polymorphism, implement a method called "walking", and the parameter type is IRunning public static void walk(IRunning running){// System.out.println("I took my partner for a walk"); running.run(); } //Forget the type, implement polymorphism, implement a method called "play", and the parameter type is ISwimming public static void play(ISwimming swimming){ System.out.println("My little friend and I are swimming"); swimming.swim(); } public static void main(String[] args) { IRunning iRunning1=new Robot();//Interfaces can be transformed upward walk(iRunning1);//Polymorphism can also occur. Call walk and pass in the parameters //For the interface, it doesn't care who passes the parameters. As long as it implements the irrunning interface, it can run. IRunning iRunning2=new Frog("frog"); walk(iRunning2); ISwimming iSwimming=new Fish("Small fish"); play(iSwimming); } }
Print results:
Interfaces can inherit an interface to achieve the effect of reuse. Using the extends keyword, the inheritance between interfaces is equivalent to merging multiple interfaces together
Interface usage instance
Sort an array of objects
Given a student class
class Student {//Implementing the Comparable interface indicates that the interface must have an abstract method public String name; public int age; public int score; public Student(String name, int age, int score) {//Provide construction method this.name = name; this.age = age; this.score = score; } //To print these three properties, you need to override the toString method @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", score=" + score + '}'; }
Give a student object array and sort the elements in the object array (in descending order by age)
public class TestDemo { public static void main(String[] args) { Student student1=new Student("Xiao Wang",18,99); Student student2=new Student("Xiao Ming",21,69); Student student3=new Student("petty thief",17,79); /*if(student1<student2){//It is wrong to compare the two students only, because I don't know what to compare, name or age, or score? Therefore, user-defined types cannot be compared. If you want to compare, you need to add implements comparable < student > after the student class. What is written in angle brackets represents what you want to compare at present }*/ /* if(student1.compareTo(student2)<0){ System.out.println("student1 Is younger than the age of student2); }*/ Student[] students=new Student[3];//Define an array, put three students in it, and sort the three students. students[0]=student1;//Student 1 placed subscript 0 students[1]=student2; students[2]=student3;
According to our previous understanding, we have a ready-made sort method for arrays. Can we use this method directly?
Arrays.sort(students);//Arrays.sort sorts from small to large by default //If you want to sort, there must be two students at the bottom for pairwise comparison System.out.println(Arrays.toString(students)); }
Error running result: exception thrown
After careful consideration, it is not difficult to find that, unlike ordinary integers, two integers can be directly compared and the size relationship is clear. How to determine the size relationship between two student objects? We need to specify it additionally
Let our Student class implement the Comparable interface and the compareTo method
class Student implements Comparable<Student>{//Implementing the Comparable interface indicates that the interface must have an abstract method public String name; public int age; public int score; public Student(String name, int age, int score) {//Provide construction method this.name = name; this.age = age; this.score = score; } //To print these three properties, you need to override the toString method @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", score=" + score + '}'; } @Override public int compareTo(Student o) {//Override the compareTo method to compare the current object with the parameters you passed //If the comparison is based on age, it can be written like this //Custom types need to specify the comparison method within compareTo, that is, from small to large or from large to small. if(this.age>o.age){//If it is greater than, it is arranged from small to large; if it is less than, it is arranged from large to small, and returns 1 return 1; }else if(this.age==o.age){//If equal, returns 0 return 0; }else {//Returns - 1, indicating less than return -1; } } }
In the sort method, the compareTo method will be called automatically. The parameter of compareTo is Object. In fact, what is passed in is an Object of Student type
Then compare the size relationship (by age) between the current object and the parameter object
- If the current object should be placed before the parameter object, a number less than 0 is returned;
- If the current object should be placed after the parameter object, a number greater than 0 is returned;
- If the current object and the parameter object are in no order, return 0
Implementation results: meet expectations
The complete code is as follows:
package com.xiaoba.demo4; import java.util.Arrays; /** * In general, when comparing user-defined types, you need to be able to compare them. By implementing the Comparable interface, you need to rewrite the compareTo method to compare whether to arrange from large to small or from small to large * Arrange the arrangement according to your own ideas */ //Comparing custom types allows this class to implement the Comparable interface class Student implements Comparable<Student>{//Implementing the Comparable interface indicates that the interface must have an abstract method public String name; public int age; public int score; public Student(String name, int age, int score) {//Provide construction method this.name = name; this.age = age; this.score = score; } //To print these three properties, you need to override the toString method @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", score=" + score + '}'; } @Override public int compareTo(Student o) {//Override the compareTo method to compare the current object with the parameters you passed //If the comparison is based on age, it can be written like this //Custom types need to specify the comparison method within compareTo, that is, from small to large or from large to small. if(this.age>o.age){//If it is greater than, it is arranged from small to large; if it is less than, it is arranged from large to small, and returns 1 return 1; }else if(this.age==o.age){//If equal, returns 0 return 0; }else {//Returns - 1, indicating less than return -1; } } } public class TestDemo { public static void main(String[] args) { Student student1=new Student("Xiao Wang",18,99); Student student2=new Student("Xiao Ming",21,69); Student student3=new Student("petty thief",17,79); /*if(student1<student2){//It is wrong to compare the two students only, because I don't know what to compare, name or age, or score? //Therefore, user-defined types cannot be compared. If you want to compare, you need to add implements comparable < student > after the student class. What is written in angle brackets represents what you want to compare at present }*/ /* if(student1.compareTo(student2)<0){ System.out.println("student1 Is younger than the age of student2); }*/ Student[] students=new Student[3];//Define an array, put three students in it, and sort the three students. students[0]=student1;//Student 1 placed subscript 0 students[1]=student2; students[2]=student3; Arrays.sort(students);//Arrays.sort sorts from small to large by default //If you want to sort, there must be two students at the bottom for pairwise comparison System.out.println(Arrays.toString(students)); } //Generally, integer types are sorted from small to large by default. Only user-defined types can control the sorting method public static void main1(String[] args) { int[] array={12,3,8,24,36,78}; Arrays.sort(array);//sort System.out.println(Arrays.toString(array)); int a=10; int b=20; if(a>b){ } } }
Note: for the sort method, each object of the array to be passed in is "comparable" and needs the ability of compareTo. You can define comparison rules by overriding the compareTo method.
Clonable interface and deep copy
For simple types, it is a deep copy: draw an example
Deep copy code example:
public class demo5 { public static void main(String[] args) { int[] array1={1,2,3,4,5}; int[] array2=array1.clone();//By cloning array1, you can clone a new array and assign it to array2. //For clone(), it is light copy. What are light copy and deep copy? /*If it is a simple type, it is a deep copy. If it is a reference type, it is a shallow copy. However, java is object-oriented, and object-oriented must be a shallow copy. Therefore, during the interview, you can directly say it as a shallow copy without being too detailed.*/ array2[0]=99; System.out.println(Arrays.toString(array1)); System.out.println(Arrays.toString(array2)); } }
Print results:
For the reference type is shallow copy: draw an example
At this time, the two references point to an object at the same time. Modify a data in person through array2
After that, the data corresponding to the array1 subscript will also be modified. At this time, the shallow copy is reached.
How to implement deep copy?
To realize deep copy, you should not only clone itself, but also clone a copy of the object. If the cloned object has a new address, array2 points to the new address. At this time, modifying array2 will not affect the value of array1, and this copy reaches deep copy.
Clonable interface
1. If you want to clone custom types, you need to implement the clonable interface. The public interface clonable {} interface is an empty interface
Interview question: why is it an empty interface?
The empty interface is also called the tag interface: that is, as long as the class implements the interface, the class can be marked for cloning.
class Person implements Cloneable{ public int age;//Stored in the object is an uninitialized simple type //2. Override the cloning method of the parent class, which is the cloning method of object @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class demo5 { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person(); Person person2 = (Person) person1.clone();//Because the return value of the clone method is object, it is necessary to cast the type to match System.out.println(person1.age); System.out.println(person2.age); System.out.println("=============modify==============="); person2.age = 99; System.out.println(person1.age); System.out.println(person2.age); }
In the above code, an uninitialized simple type age is stored in the object. It only takes two steps to clone the user-defined type
Step 1: you need to implement the clonable interface
Step 2: override the cloning method of the parent class. You only need the default.
Question: is it a deep copy or a shallow copy?
The cloning method itself is a shallow copy.
class Money{//Define a money class double money=39.9;//There is a money in the class, with an initial value of 39.9 } class Person implements Cloneable{ public int age;//Stored in the object is an uninitialized simple type Money m=new Money();//Define a Money in the Person class and instantiate an object //2. Override the cloning method of the parent class, which is the cloning method of object @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class demo5 { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person(); Person person2 = (Person) person1.clone(); System.out.println(person1.m.money); System.out.println(person2.m.money); System.out.println("=============modify==============="); person2.m.money=99.9; System.out.println(person1.m.money); System.out.println(person2.m.money); } //After replacing a simple type with a reference type, it becomes a shallow copy
Print results:
How to do deep copy?
Step 1: let Money implement the clone interface
Step 2: rewrite the cloning method
class Money implements Cloneable{//Define a money class double money=39.9;//There is a money in the class, with an initial value of 39.9 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable{ public int age;//Stored in the object is an uninitialized simple type Money m=new Money();//Define a Money in the Person class and instantiate an object //2. Override the cloning method of the parent class, which is the cloning method of object @Override protected Object clone() throws CloneNotSupportedException { //return super.clone(); //1. Clone person Person p=(Person) super.clone();//Clone the current object and assign it to p //2. Clone the current Money object p.m=(Money) this.m.clone();//Clone the m of the current object and give it to the M generated in p. at this time, it points to a new object to achieve the purpose of deep copy //3. after cloning, the clone is called, and the reference is returned to person2. return p; } } public class demo5 { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person(); Person person2 = (Person) person1.clone(); System.out.println(person1.m.money); System.out.println(person2.m.money); System.out.println("=============modify==============="); person2.m.money=99.9; System.out.println(person1.m.money); System.out.println(person2.m.money); }
Print results:
Summary:
Encapsulation: it mainly modifies some fields and methods through the private keyword. If the fields and methods are modified by the private keyword, they can only be accessed in the current class, not out of this class, that is, its scope is in this class.
- Advantages of encapsulation: the cost of using the class by the caller of the class is further reduced.
Inheritance: inheritance indicates the relationship between them through the extends keyword, which refers to the subclass / derived class extends (inherited from) the parent class / base class / superclass. In inheritance, except that the construction method is not inherited, everything else is inherited.
- The difference between super keyword and this keyword:
- When a subclass is constructed, it should help the parent class to construct
- private modifier, default modifier (package access permission), protected (it appears to solve the problem of inheritance) and public. The size relationship of these four access permissions is arranged from small to large.
- The difference between rewriting and overloading:
- The access modifier qualifier of the subclass must be greater than or equal to the access modifier qualifier of the parent class.
- Upward transformation
- Runtime binding / dynamic binding
- The parent class reference refers to the child class object, and the parent class and child class have an override method with the same name. Calling the override (override) method with the same name through the parent class reference will lead to runtime binding.
- Understanding polymorphism: the mechanism that a reference can point to different objects and call the same method to show different runtime States is called polymorphism.
- Abstract class: a class containing abstract methods is called an abstract class and is decorated with the keyword abstract.
- Abstract methods have no concrete implementation
- Abstract classes cannot be new (instantiated)
- The purpose of abstract classes is to be inherited
- If a class inherits the abstract class, it must rewrite the abstract methods in the abstract class. If the class does not want to implement it, it will turn the class into an abstract class. However, it will be implemented sooner or later, because the abstract class cannot be instantiated and can only be inherited.
Interface: decorated with the interface keyword
- For its member variable: public static final (static variable)
- For its member method: public abstract (abstract method)
- Interfaces cannot be instantiated either
- The implementation interface uses the implements keyword to implement multiple interfaces.
- The appearance of interfaces is mainly to solve the problem of multiple inheritance in Java, because Java is single inheritance. If you want multiple inheritance, you need to implement multiple interfaces to realize multiple inheritance
- Comparable interface
- To compare custom types, you need to implement this interface. There is a compareTo method in this interface.
- The comparable interface is mainly used to compare objects in Java.
Common interview questions:
Differences between abstract classes and interfaces: core differences: abstract classes can contain ordinary methods and fields. Such ordinary methods and fields can be directly used by subclasses (without rewriting), while interfaces cannot contain ordinary methods, and subclasses must override all abstract methods.
As in the example of Animal written before, the Animal here contains an attribute such as name, which exists in any subclass. Therefore, the Animal here can only be used as an abstract class, not an interface.
class Animal { protected String name; public Animal(String name) { this.name = name; } }
The significance of abstract classes is to enable the compiler to better verify. We will not use classes like Animal directly, but use its subclasses. In case we accidentally create an instance of Animal, the compiler will remind us in time
NO | difference | abstract class | Interface |
---|---|---|---|
1 | Structural composition | Ordinary class + abstract method | Abstract method + global constant |
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 inherit only one abstract class | A word class can implement multiple interfaces |