This is the 19th day of my participation in the August Wenwen Challenge.More challenges in August
define
Multiple representations of a subclass to its parent
Define a parent class that, by way of inheritance, gets multiple different subclasses. Although we always operate on a reference to a parent class, the reference actually refers to a subclass, and the method we call a parent class reference is dynamically bound to the subclass’s method (if the subclass overrides the method).
The code on
Define two classes that have inheritance relationships
class Super{
int a = 1;
void f(a){
System.out.print("Super.f()"); }}class Sub extends Super{
int a = 2;
void f(a){
System.out.print("Sub.f()");
}
void g(a){
System.out.print("Sub.g()"); }}Copy the code
The most common encoding method is to instantiate a subclass and receive the instance with the corresponding type
Sub sub = new Sub();
Copy the code
Alternatively, we accept the instance using the parent type of this type, as follows, which is also called an upcast
Super super = new Sub();
Copy the code
details
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Super sup = new Super();
sup.a; / / 1
sup.f(); // Super.f()
Sub sub = new Sub();
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
sub.a; / / 2
sub.f(); // Sub.f();
sub.g(); // Sub.g();
/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Super sup2 = new Sub();
sup2.a; / / 1
sup2.f(); // Sup.f();
Sub sub2 = (Sub)sup2;
sub2.a; / / 2
sub2.g(); // Sup.g()
Copy the code
In part 1, 2
Instantiate an object and receive it with its corresponding type. Normal use
Part 3
Since Super is used to receive instances of Sub, a normal access to variables and methods should be related to the access of Super. However, due to Java’s dynamic binding mechanism, the JVM runs and finds that we actually pass in a Sub?? Then, our call to sup.f() is handled by the JVM as a call to sub.f(), which is the multiple representations of subclasses to their parents
Since we received an instance using Super, we can use any method on Super; We confirm that the instance is Sub, and want to use a method specific to Sub, or a variable corresponding to Sub, we can force Sub Sub = (Sub)sup;
A template model
abstract class Template{
public void func(a){
f();
g();
}
abstract void f(a);
abstract void g(a);
}
class A extends Template{
void f(a){};
void g(a){};
}
class B extends Template{
void f(a){};
void g(a){};
}
Template t = new A();
t.func();
Copy the code
We define an abstract class Template, and then write a common processing method func() in it. At the same time, we define specific details that cannot be handled in the common processing logic as abstract methods to be implemented separately by subclasses, or described as requirements to be implemented by different subclasses
When we write polymorphic code, instantiate an A, receive it with the Template type, and then call func(), the JVM helps us dynamically bind to the corresponding methods of type A (f(), g()).
The appendix
upcasting
Because of inheritance, upcasting always has an IS A relationship, and upcasting a type to its parent class means losing subclass-specific methods and members, and such conversions from wide to narrow scope are supported in Java
In the Java base type, we use a higher precision type to receive the current data, which is allowed by default. If we receive high-precision data with a lower-precision type, there will be a loss of precision. In this case, we need to display a mandatory indication that we know the consequences of the operation
Precision from bottom to top: char -> byte -> short -> int -> long -> float -> double
Downward transition
Contrary to upward transition, we reference to a parent class instance, expect into a specific subclasses, and use the subclass specific methods, it is a big problem, usually a parent will have innumerable subclasses, the JVM does not know the actual type of the instance, if we need, also can be strong, operation is as follows
Super sup = new Sub();
Sub sub = (Sub)sup;
// Sub2 sub2 = (Sub2)sup; // ClassCastException !!
Copy the code
Of course, we need to be careful, otherwise we will see a ClassCastException (NPE -> NullPointExpection).