Java object oriented programming

Posted by kumschick on Sat, 20 Nov 2021 06:08:50 +0100

catalogue

package

Import classes in package

Static import

Common system packages

inherit

rule of grammar

protected keyword

  final keyword

polymorphic

Upward transformation

  Method rewrite

  Dynamic binding

  Understanding polymorphism

Downward transformation

abstract class

rule of grammar:

  Role of abstract classes

  Interface

rule of grammar

  Comparable and Clonable interfaces

 Comparable

 Clonable

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

  1. java.lang: system common basic classes (String, Object). This package is automatically imported from JDK1.1;
  2. java.lang.reflect:java reflection programming package;
  3. java.net: network programming development package;
  4. java.sql: support package for database development;
  5. java.util: a tool package provided by java; (very important)
  6. 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:

  1.   Override permission in subclass > = permission of parent class
  2. The method return value of the subclass must be consistent with that of the parent class (except for upward transformation)
  3. Ordinary methods can be overridden, but static methods modified by static cannot be overridden
  4. 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:

  1.   The cost of using classes by class callers is further reduced
  2. It can reduce the "loop complexity" of the code and avoid using a large number of if - else
  3. 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:

  1. 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)
  2. 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:

  1.   Abstract classes are defined by abstract, and abstract classes are a superset of ordinary classes
  2. Abstract classes only have one more method than ordinary classes
  3. 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:

  1.   When we create an interface, the name of the interface usually starts with the capital letter I
  2. Interface naming generally uses the word of "adjective"
  3. Ali coding specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise
  4. Subclass naming: interface name + impl
  5. Multiple interfaces can inherit the parent interface with extensions
  6. If a class inherits abstract classes and implements interfaces at the same time, first extend a class, and then implement multiple interfaces
  7. 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.

Topics: Java OOP