1. In the experiment, use the debug function of IDE to set breakpoints for the new statements of examples 6.4 and 6.5, use step into / step over to track the execution sequence of subclass object instantiation (initialization), and summarize the process
Example 6.4
//Example 6.4: explicitly using super to call the constructor of the parent class class AddClass { private int x=0,y=0,z=0; AddClass (int x) { this.x=x; } AddClass (int x,int y) { this(x); this.y=y; } AddClass (int x,int y,int z) { this(x,y); this.z=z; } public int add() { return x+y+z; } } public class SonAddClass extends AddClass{ int a=0,b=0,c=0; SonAddClass (int x) { super(x); a=x+7; } SonAddClass (int x,int y){ super(x,y); a=x+5; b=y+5; } SonAddClass (int x, int y,int z){ super(x,y,z); a=x+4; b=y+4; c=z+4; }//What happens if super(x,y,z) is removed? public int add() { System.out.println("super:x+y+z="+super.add()); return a+b+c; } public static void main(String[] args){ SonAddClass p1=new SonAddClass (2,3,5); SonAddClass p2=new SonAddClass (10,20); SonAddClass p3=new SonAddClass (1); System.out.println("a+b+c="+p1.add()); System.out.println("a+b="+p2.add()); System.out.println("a="+p3.add()); } }
Example 6.5
//Example 6.5: implicitly using super to call the constructor of the parent class class Pare { int i=3; Pare(){ System.out.println("call super()"); } } class Construct extends Pare { int i = 10; Construct() { System.out.println("execute Construct()"); } Construct(int num) { this(); //What if you remove this sentence? System.out.println("execute Construct(int)"); } public static void main(String[] args) { Construct ct = new Construct(9); System.out.println(ct.i); } } //Output: /**call super() execute Construct() execute Construct(int) 10*/
Execution sequence:
1. Allocate memory space for subclass objects and initialize member variables by default.
2. Call the subclass construction method corresponding to the incoming parameter, and pass the parameter in new to the formal parameter of the construction method.
3. Explicitly or implicitly call the super method to initialize the parent class.
4. Execute the initialization field, and finally carry out the remaining statements of the subclass initialization method.
Note: the parent class is initialized first, and the super method will be called. If the parent class has a parameter construction method, the default parameter free construction needs to be written by itself.
2. Please give an example of how to protect messages between two objects
The essence of the message is to refer to the service request sent to the object, which is the call of data members and member methods. By using the reference of one object to call the data members or member methods of another object, the two objects are connected together to realize the sending of the message.
give an example:
class A{ private int value; public A(int value){ this.value=value; } public void speak(){ System.out.println(value); } } class B{ A a; public B(A a){ this.a=a; } } public class test{ public static void main(String[] args) { A a=new A(9); B b=new B(a); b.a.speak();//9 } }
3. Talk about the difference between combination and inheritance and their usage scenarios (i.e. when should combination be used? When should inheritance be used?)
Difference: the combination phenomenon is that the object reference of one class is the property of another class. The object reference can point to any object of its corresponding class, with low coupling, but the object can only call its specified methods and cannot be modified; inheritance is that the subclass inherits all the properties and methods of the parent class, and the subclass can overload and overwrite the methods of the parent class. Inheritance has a similar pair One property, high coupling.
Composite scenarios should be used: the object of one class has a one to many relationship with the object of another class, and the method of one class will never change for another class.
Inheritance scenarios should be used: objects of two classes have a one-to-one relationship, and one class needs to overload or override the methods of the other class; abstract classes.
Composition only combines two classes. One class is the domain variable of the other class. There is no parent-child relationship between the two classes. Inheritance is the relationship that must be established by the parent class if the child class is established. Therefore, composition is used when you only need to use the methods of another class, but inheritance is used when you need to use the methods of another class.
4. What is the meaning and function of runtime polymorphism in Java? Please give an example
Runtime polymorphism: when the same reference variable (parent class reference) Point to different subclass instances, and then access the methods that reference variable members. In other words, runtime polymorphism is rewriting, that is, subclass methods override parent methods. When using parent class references to point to subclass objects and then call methods in a parent class, different subclasses will show different results.
What it does: runtime polymorphism provides more flexibility because everything is resolved at runtime.
//Parent class class A { void fun() { System.out.println("I am A"); } } //Subclass B of A class B extends A { void fun() { System.out.println("I am B"); } } //Subclass C of A class C extends A { void fun() { System.out.println("I am C"); } } class Test { public static void main(String[] args) { //Defining parent object reference variables A a; //Subclass object B b = new B(); C c = new C(); //Parent object reference variable references child object a=b; a.fun(); //Output I am B a=c; a.fun(); // //Output I am C } }
5. Rewrite the program in example 6.8 using the interface
interface Shapes{ public abstract double getArea(); public abstract double getPerimter(); } class Rect implements Shapes{ private double x,y; public Rect(double x,double y){ this.x=x; this.y=y; } public double getArea(){ return x*y; } public double getPerimter(){ return 2*(x+y); } } class Triangle implements Shapes{ private double x,y,z,m; public Triangle(double x,double y,double z){ this.x=x; this.y=y; this.z=z; this.m=x+y+z; } public double getArea(){ return(Math.sqrt(m+(m-x)*(m-y)*(m-z))); } public double getPerimter(){ return x+y+z; } } class Circle implements Shapes{ private int r; public Circle(int r){ this.r=r; } public double getArea(){ return Math.PI*r*r; } public double getPerimter(){ return 2*Math.PI*r; } } public class test{ public static void main(String[] args) { Rect r=new Rect(10,20); Triangle t=new Triangle(10, 20, 30); Circle c=new Circle(10); printArea(r); printPerimter(r); printArea(t); printPerimter(t); printArea(c); printPerimter(c); /** Rect Area:200.0 Rect Perimter:60.0 Triangle Area:245.07141816213493 Triangle Perimter:60.0 Circle Area:314.1592653589793 Circle Perimter:62.83185307179586 */ } public static void printArea(Shapes s){ System.out.println(s.getClass().getName()+" Area:"+s.getArea()); } public static void printPerimter(Shapes s){ System.out.println(s.getClass().getName()+" Perimter:"+s.getPerimter()); } }
6. Customize a class and override the equals method to meet your business needs
class Person{ private String name; private int age; private int weight; public String getName(){ return name; } public int getAge(){ return age; } public int getWeight(){ return weight; } public Person(String name,int age,int weight){ this.name=name; this.age=age; this.weight=weight; } @Override public boolean equals(Object o){ if(getName()==((Person)o).getName()&&getAge()==((Person)o).getAge()&&getWeight()==((Person)o).getWeight()){ return true; }else{ return false; } } } public class test{ public static void main(String[] args) { Person p1=new Person("zma",19,120); Person p2=new Person("zma",19,120); Person p3=new Person("zma",18,130); System.out.println(p1.equals(p2));//true; System.out.println(p2.equals(p3));//false; } }
7. Illustrate the usage scenario of the operator instanceof
a instanceof A:
Where a is the object and a is the class
1. If A is an instance of A or an example of A subclass, return true
2.a returns false for the example of parent class A
3.a has nothing to do with a, compilation error
class Animal{ public void getName(){} public void getAge(){} } class Dog extends Animal{ private String name; private int age; Dog(String name,int age){ this.name=name; this.age=age; } @Override public void getName(){ System.out.println("Dog's name is:"+name); } @Override public void getAge(){ System.out.println("Dog's name is:"+age); } } class Person{} public class test{ public static void main(String[] args){ Animal a=new Animal(); Dog d=new Dog("jack",5); Person p=new Person(); System.out.println(d instanceof Animal);//true; System.out.println(a instanceof Dog);//false; // System.out.println(p instanceof A); compilation error Incompatible conditional operand types Person and A } }
instanceof application scenario
Avoid exceptions when the parent class references the child class example to transition upward and transition downward again
8. Talk about the similarities and differences between abstract classes and interfaces and their use scenarios
1. Usage scenarios of abstract classes
You want to constrain subclasses to have common behavior (but no longer depend on how to implement it), have default methods, and have instance variables
For example, the template method design pattern enables subclasses to redefine the specific implementation of some steps in the algorithm without changing the algorithm structure.
2. Application scenario of interface
① Constrains multiple implementation classes to have uniform behavior, but does not care how each implementation class is implemented
② As an identifier that can realize specific functions, it can also be a pure identifier that does not exist in any interface method.
③ Implementation classes need to have many different functions, but there may be no connection between the functions.
④ Use the reference of the interface to call the methods implemented in the concrete implementation class (polymorphic)