catalogue
Comparable and Clonable interfaces
package
Folder, package is a way to organize classes. The main purpose of using package is to ensure the uniqueness of classes
Import classes in package
Import a class: import package name. Class name
Import all classes in the package: import package name*
Static import
Use import static to import static methods and fields in a package
For example:
import static java.lang.Math.*; public class Test { public static void main(String[] args) { double x = 30; double y = 40; // Static import is more convenient to write // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); double result = sqrt(pow(x, 2) + pow(y, 2)); System.out.println(result); } }
Import the static field in the class. This way can make it easier to write some code.
Common system packages
- java.lang: system common basic classes (String, Object). This package is automatically imported from JDK1.1;
- java.lang.reflect:java reflection programming package;
- java.net: network programming development package;
- java.sql: support package for database development;
- java.util: a tool package provided by java; (very important)
- java.io:I/O programming development kit.
Package access: Default (no need to write it out), which is visible in all classes under the current package.
inherit
rule of grammar
class Subclass extends Parent class { }
- Use extends to specify the parent class
- A subclass in Java can only inherit one parent class (while languages such as C++/Python support multiple inheritance)
- Subclasses inherit all public fields and methods of the parent class
- private fields and methods of the parent class are inaccessible in subclasses
- The instance of a subclass also contains the instance of the parent class. You can use the super keyword to get a reference to the instance of the parent class
For example, chestnuts:
class Animal { public String name; public Animal(String name) { this.name = name; } public void eat(String food) { System.out.println(this.name + "I am eating" + food); } } class Cat extends Animal { public Cat(String name) { // Use super to call the constructor of the parent class super(name); } } class Bird extends Animal { public Bird(String name) { super(name); } public void fly() { System.out.println(this.name + "Flying ︿( ̄︶ ̄)︿"); } } public class Test { public static void main(String[] args) { Cat cat = new Cat("Xiao Hei"); cat.eat("Cat food"); Bird bird = new Bird("round"); bird.fly(); } }
Cat and Bird inherit from Animal. Cat and Bird are subclasses of Animal, and Animal is the parent of cat and Brid.
Inheritance access permission: visible between classes with inheritance relationship under different packages.
protected keyword
If the field is set to private, the subclass cannot be accessed. But setting it to public violates our original intention of "encapsulation". The best way to achieve the best of both worlds is the protected keyword
- The fields and methods modified by protected are inaccessible to the caller of the class
- For subclasses of a class and other classes in the same package, the fields and methods modified by protected are accessible
There are four access permissions for fields and methods in Java:
- private: it can be accessed inside the class, but not outside the class
- Default (also called package access permission): it can be accessed inside a class. Classes in the same package can be accessed, but other classes cannot
- protected: it can be accessed inside a class. Subclasses and classes in the same package can be accessed. Other classes cannot be accessed
- public: both inside the class and the caller of the class can access it
final keyword
When modifying a variable or field, it indicates a constant (cannot be modified). The final keyword can also modify a class. At this time, it indicates that the modified class cannot be inherited (that is, the class will not have subclasses)
final public class Animal { } public class Bird extends Animal { } // Compilation error Error:java: Unable to start from the final Animal Inherit
polymorphic
Upward transformation
For example, chestnuts:
Bird bird = new Bird("round");
This line of code can also be written as follows:
Bird bird = new Bird("round"); Animal bird2 = bird; // Or write it in the following way Animal bird2 = new Bird("round");
At this time, bird2 is a reference to the parent class (Animal) and points to an instance of a child class (Bird). This writing is called upward transformation
Syntax:
Parent class name Parent class reference = new Subclass ()
Timing of upward Transformation:
- Direct assignment
- Method transmission parameter
- Method return
Method rewrite
The subclass implements the method with the same name as the parent class, and the type and number of parameters are exactly the same. This situation is called override
matters needing attention:
- Override permission in subclass > = permission of parent class
- The method return value of the subclass must be consistent with that of the parent class (except for upward transformation)
- Ordinary methods can be overridden, but static methods modified by static cannot be overridden
- For overridden methods, you can use the @ Override annotation to specify them explicitly
Dynamic binding
What happens when a method with the same name appears in the subclass and parent class?
// Animal.java public class Animal { protected String name; public Animal(String name) { this.name = name; } public void eat(String food) { System.out.println("I am a small animal"); System.out.println(this.name + "I am eating" + food); } } // Bird.java public class Bird extends Animal { public Bird(String name) { super(name); } public void eat(String food) { System.out.println("I am a bird"); System.out.println(this.name + "I am eating" + food); } } // Test.java public class Test { public static void main(String[] args) { Animal animal1 = new Animal("round"); animal1.eat("millet"); Animal animal2 = new Bird("flat "); animal2.eat("millet"); } } // results of enforcement I am a small animal Yuanyuan is eating millet I am a bird Bian Bian is eating millet
At this point, we find that:
Although animal1 and animal2 are instances of Animal type, However, animal1 points to an instance of Animal type and animal2 points to an instance of Bird type.
Call eat methods for animal1 and animal2 respectively. It is found that animal1.eat() actually calls the methods of the parent class, while animal2.eat() actually calls the methods of the child class.
Therefore, just look at who is new and call whose method.
Understanding polymorphism
Polymorphism: when a reference calls the same method in different scenarios, it shows different behavior.
For example, chestnuts:
class Shape { public void draw() { // Don't do anything } } class Cycle extends Shape { @Override public void draw() { System.out.println("○"); } } class Rect extends Shape { @Override public void draw() { System.out.println("□"); } } class Flower extends Shape { @Override public void draw() { System.out.println("♣"); } } /I am the dividing line// // Test.java public class Test { public static void main(String[] args) { Shape shape1 = new Flower(); Shape shape2 = new Cycle(); Shape shape3 = new Rect(); drawMap(shape1); drawMap(shape2); drawMap(shape3); } // Print a single drawing public static void drawShape(Shape shape) { shape.draw(); } }
When the caller of a class writes the drawMap method, the parameter type is shape (parent class). At this time, he does not know or pay attention to the instance of which type (subclass) the current shape reference points to. At this time, the reference of shape may call the draw method in many different ways (related to the instance corresponding to shape) , this behavior is called polymorphism.
Polymorphism, as the name suggests, is "a reference can show many different forms", which is method rewriting + upward transformation,
Benefits of using polymorphism:
- The cost of using classes by class callers is further reduced
- It can reduce the "loop complexity" of the code and avoid using a large number of if - else
- More extensible (when a new subclass is generated, due to polymorphism, the caller only needs to create an instance of the new class)
Downward transformation
Upward transformation means that a subclass object is transformed into a parent object, and downward transformation means that a parent object is transformed into a subclass object
Syntax:
Subclass Subclass reference = (subclass) parent class reference
matters needing attention:
Downward transformation may make mistakes. There are two ways to avoid mistakes:
- Use the instanceof keyword provided by Java (instanceof can determine whether a reference is an instance of a class. If so, it returns true. At this time, it is safer to carry out downward transformation)
- To use the downward transformation, the upward transformation must first occur (the core is that the object using the downward transformation happens to be the object of the current upward transformation new)
For example: Animal a1 = new Bird();
Bird bird = (Bird) a1;
abstract class
rule of grammar:
In the example of printing graphics just now, 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 completed by the draw methods of various subclasses of Shape. For this method without actual work, we can design it as an abstract method, and the class containing abstract methods is called abstract class (abstract class).
abstract class Shape { abstract public void draw(); }
- Add the abstract keyword before the draw method to indicate that it is an abstract method. At the same time, the abstract method has no method body (without {}, it cannot execute concrete code)
- For a class containing abstract methods, the abstract keyword must be added to indicate that it is an abstract class
matters needing attention:
- Abstract classes are defined by abstract, and abstract classes are a superset of ordinary classes
- Abstract classes only have one more method than ordinary classes
- Abstract methods are defined using abstract, with only method declarations and no method body
Role of abstract classes
Abstract classes exist in order to be inherited
The abstract class itself cannot be instantiated. If you want to use it, you can only create a subclass of the abstract class. Then let the subclass override the abstract methods in the abstract class
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
rule of grammar
-
Use interface to define an interface
-
The methods in the interface must be abstract methods, so abstract can be omitted
-
The methods in the interface must be public, so you can omit public
-
Use 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
matters needing attention:
- When we create an interface, the name of the interface usually starts with the capital letter I
- Interface naming generally uses the word of "adjective"
- Ali coding specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise
- Subclass naming: interface name + impl
- Multiple interfaces can inherit the parent interface with extensions
- If a class inherits abstract classes and implements interfaces at the same time, first extend a class, and then implement multiple interfaces
- After JDK 8, common methods are also allowed in the interface
Comparable and Clonable interfaces
Some useful interfaces are built into Java, such as Comparable and Clonable.
Comparable
CompareTo method in Comparable interface: return value int
- 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;
Clonable
Indicates the ability to clone.
Shallow copy:
When an object comes out through another object clone, the two objects are independent objects, but the other objects contained in the two objects are the same. This copy becomes a shallow copy.
Cloneable copies an object as a "shallow copy"
Look at the following code:
public class Test { static class A implements Cloneable { public int num = 0; @Override public A clone() throws CloneNotSupportedException { return (A)super.clone(); } } static class B implements Cloneable { public A a = new A(); @Override public B clone() throws CloneNotSupportedException { return (B)super.clone(); } } public static void main(String[] args) throws CloneNotSupportedException { B b = new B(); B b2 = b.clone(); b.a.num = 10; System.out.println(b2.a.num); } } // results of enforcement 10
The b object copied through the clone only copies the b itself, not the a object contained inside. At this time, the a reference contained in b and b2 still points to the same object. At this time, when one side is modified, the other side will also be changed
Deep copy:
A is copied from B. at this time, all other references contained in a and B are also independent. This copy becomes a deep copy.
Deep copy can be implemented by serializing or nesting clone methods.