12 abstract class, polymorphism, root parent class

Posted by apol on Wed, 26 Jan 2022 03:48:25 +0100

abstract class

definition

  • Abstract class: a class modified by abstract
  • Abstract method: a method without a method body
  • The class containing abstract methods must be abstract

matters needing attention

  • Abstract classes cannot create objects
  • Abstract classes can have constructors. Used for initializing parent class members when subclasses create objects
  • Abstract classes do not necessarily contain abstract methods, but classes with abstract methods must be abstract classes
  • Subclasses that inherit an abstract class must override all abstract methods of the parent class

Abstract class exercises

public abstract class Person {
	public abstract void walk();
	public abstract void eat();
}
public class Man extends Person {

	@Override
	public void walk() {
		System.out.println("Walk with great strides");
	}

	@Override
	public void eat() {
		System.out.println("Wolf down a meal");
	}

	public void smoke(){
		System.out.println("smoke opium");
	}
}

polymorphic

  • Definition: the same behavior has multiple different manifestations

premise

  • Inherit the parent class or implement the interface
  • Method override
  • A parent class reference points to a child class object

Embodiment of polymorphism

  • Compile to see the parent class
    • Only the methods declared by the parent class can be called, and the methods extended by the child class cannot be called
  • Run to see subclasses
    • It must be the method body that performs subclass overrides

Polymorphic practice

public abstract class Employee {
	private String name;

	public Employee(String name) {
		super();
		this.name = name;
	}

	public Employee() {
		super();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public abstract double earning();

	public String getInfo() {
		return "full name:" + name + ",Paid salary:" + earning();
	}
}
public class SalaryEmployee extends Employee {
	private double salary;
	private int workingDays;//Number of working days,
	private double offDays;//Leave days

	public SalaryEmployee() {
		super();
	}

	public SalaryEmployee(String name,  double salary, int workingDays, double offDays) {
		super(name);
		this.salary = salary;
		this.workingDays = workingDays;
		this.offDays = offDays;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public int getWorkingDays() {
		return workingDays;
	}

	public void setWorkingDays(int workingDays) {
		this.workingDays = workingDays;
	}

	public double getOffDays() {
		return offDays;
	}

	public void setOffDays(double offDays) {
		this.offDays = offDays;
	}

	/*
	 * Rewrite the method, and public double earning() returns the paid salary, 
		Paid salary = salary - salary / working days * leave days
	 */
	@Override
	public double earning() {
		return salary - salary/workingDays * offDays;
	}

}
public class HourEmployee extends Employee {
	private double moneyPerHour;
	private double hours;
	
	public HourEmployee() {
		super();
	}

	public HourEmployee(String name, double moneyPerHour, double hours) {
		super(name);
		this.moneyPerHour = moneyPerHour;
		this.hours = hours;
	}

	public double getMoneyPerHour() {
		return moneyPerHour;
	}

	public void setMoneyPerHour(double moneyPerHour) {
		this.moneyPerHour = moneyPerHour;
	}

	public double getHours() {
		return hours;
	}

	public void setHours(double hours) {
		this.hours = hours;
	}

	/*
	 * Rewrite the method, and public double earning() returns the paid salary, 
		Paid salary = how much per hour * hours	
	 */
	@Override
	public double earning() {
		return moneyPerHour * hours;
	}
}
public class Manager extends SalaryEmployee {
	private double commisionPer;

	public Manager() {
		super();
	}

	public Manager(String name,  double salary, int workingDays, double offDays, double commisionPer) {
		super(name, salary, workingDays, offDays);
		this.commisionPer = commisionPer;
	}

	public double getCommisionPer() {
		return commisionPer;
	}

	public void setCommisionPer(double commisionPer) {
		this.commisionPer = commisionPer;
	}

	@Override
	public double earning() {
		return super.earning() * (1+commisionPer);
	}
}
public class TestEmployee {
	public static void main(String[] args) {
		Employee[] all = new Employee[3];
		
		all[0] = new HourEmployee("Zhang San", 50, 50);
		all[1] = new SalaryEmployee("Li Si", 10000, 22, 1);
		all[2] = new Manager("Lao Wang", 20000, 22, 0, 0.3);
		
		double sum = 0;
		for (int i = 0; i < all.length; i++) {
			System.out.println(all[i].getInfo());
			sum += all[i].earning();
		}
		System.out.println("total:" + sum);
	}
}

Type conversion between parent and child classes

Upward transformation

  • Polymorphism itself is the process of converting a subclass type to a parent type, which is the default

Downward transformation

  • The process of converting a parent class type to a child class type. This process is mandatory

Why transformation

  • Polymorphism is to call subclass specific methods

Type conversion exception: ClassCastException

public class Test {
    public static void main(String[] args) {
        // Upward transformation  
        Animal a = new Cat();  
        a.eat();               // Cat eat is called

        // Downward transformation  
        Dog d = (Dog)a;       
        d.watchHouse();        // What is called is Dog's watchHouse
    }  
}

instanceof operator

public class Test {
    public static void main(String[] args) {
        // Upward transformation  
        Animal a = new Cat();  
        a.eat();               // Cat eat is called

        // Downward transformation  
        if (a instanceof Cat){
            Cat c = (Cat)a;       
            c.catchMouse();        // catchMouse of Cat is called
        } else if (a instanceof Dog){
            Dog d = (Dog)a;       
            d.watchHouse();       // The call is Dog's watchHouse
        }
    }  
}

Properties and static methods have no polymorphism

Attribute has no polymorphism

  • If you access member variables directly, you only look at the compile time type

    public class TestField {
    	public static void main(String[] args) {
    		Father f = new Son();
    		System.out.println(f.x);//Just look at compile time type x=1
    	}
    }
    class Father{
    	int x = 1;
    }
    class Son extends Father{
    	int x = 2;
    }
    

Static methods have no polymorphism

public class TestField {
	public static void main(String[] args) {
		Father f = new Son();
		f.test();//Just look at the compile time type
	}
}
class Father{
	public static void test(){
		System.out.println("father");
	}
}
class Son extends Father{
	public static void test(){
		System.out.println("son");
	}
}

native keyword

  • Native: local, native
  • You can only modify a method. The method body code representing this method is not implemented in Java language

Modifier used with the problem

Modifier that cannot be used with abstract

  • Final: and final cannot modify methods and classes together
  • Static: and static cannot modify methods together
  • Private: and private cannot modify methods together

static is used with final

  • Modification method: Yes, because none can be overridden
  • Decorated member variable: Yes, it represents a static constant
  • Modify local variables: No, static cannot modify local variables
  • Decorate code block: No, final cannot decorate code block
  • Modify internal classes: member internal classes can be modified together, but local internal classes cannot be modified together

Object root parent class

public String toString():

public class Person {  
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
    }

    // Omit constructor and Getter Setter
}

public final Class<?> Getclass(): get the runtime type of the object

public static void main(String[] args) {
	Object obj = new String();
	System.out.println(obj.getClass());//Runtime type
}

public int hashCode(): returns the hash value of each object

public static void main(String[] args) {
	System.out.println("Aa".hashCode());//2112
	System.out.println("BB".hashCode());//2112
}

public boolean equals(Object obj):

  • Used to judge whether the current object this is "equal" to the specified object obj
  • By default, it is equivalent to "= =" and compares the address value of the object
  • You can override it, but you must override the hashCode() method together