Object oriented programming in Java se

Posted by kranthi117 on Sat, 12 Feb 2022 10:33:47 +0100

catalogue

1, Abstract class

1. Concept

2. Grammar rules

3. Some precautions

4. Role of abstract classes

2, Interface

1. Elaboration

2. Grammar rules

3. Some writing standards

4. Implement multiple interfaces

5. Inheritance between interfaces

6. Interface usage examples

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);
   }
}
In this example of printing graphics , We found , Parent class Shape Medium draw The method seems to have no practical work , The main graphics are drawn by various subclasses of Shape draw Method to complete . A method like this that doesn't actually work , We can design it into a Abstract method (abstract method) , Classes that contain abstract methods are called abstract class (abstract class)

2. Grammar rules

abstract class Shape { 
    abstract public void draw(); 
}
stay draw Add method before abstract keyword , Indicates that this is an abstract method . At the same time, abstract methods have no method body ( No, { }, Cannot execute specific code) For classes that contain abstract methods, Must add abstract Keyword indicates that this is an abstract class
Therefore, the above code for printing graphics can be optimized as follows:
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

Abstract classes exist in order to be inherited The abstract class itself cannot be instantiated, To use , Only subclasses of this abstract class can be created Then let the subclass override the abstract method in the abstract class. Ordinary classes can also be inherited, and ordinary methods can also be overridden, However, the use of abstract classes is equivalent to an extra check of the compiler

2, Interface

1. Elaboration

Interface is a further step of abstract class . Abstract classes can also contain non abstract methods , And fields . The methods contained in the interface are abstract methods , Fields can only contain static constants

2. Grammar rules

In the code of printing graphics just now , Our parent class Shape No other non abstract methods are included , It can also be designed as an interface
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"

Extensions vs. implementations: extension refers to the further expansion of functions when certain functions already exist; Implementation means that there is nothing at present and it needs to be constructed from scratch

(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

(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) Alibaba coding specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise

4. Implement multiple interfaces

Sometimes we need to make a class inherit from multiple parent classes at the same time . This thing is passed in some programming languages Multiple inheritance The way to achieve However, Java Only single inheritance is supported in , A class can only extends A parent class . However, multiple interfaces can be implemented at the same time , It can also achieve the similar effect of multi inheritance
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

Object There is one in the class clone method , Call this method to create an object " Copy ". But if you want to call it legally clone method , Clonable must be implemented first Interface , Otherwise, it will be thrown CloneNotSupportedException abnormal
Cloneable interface is an empty interface, which is a flag interface, representing that the current class can be cloned
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

Nodifferenceabstract classInterface
1Structural compositionOrdinary class + abstract methodAbstract method + global variable
2jurisdictionVarious permissionspublic
3Subclass useUse the extends keyword to inherit abstract classesUse the implements keyword to implement the interface
4relationshipAn abstract class can implement several interfacesInterfaces cannot inherit abstract classes, but interfaces can inherit multiple parent interfaces using the extends keyword
5Subclass restrictionsA subclass can only inherit one abstract classA subclass can implement multiple interfaces

Topics: Java Back-end JavaSE