Get to know the java-12.6 interface and type information from the beginning (how to directly call all methods of the class by bypassing the interface)
In this section, we will discuss the interface and type information.
In the previous chapter, we mentioned interfaces. The parent class references subclass objects and then narrow down the methods. However, when we learn reflection in this chapter, this constraint becomes less strict.
Let's take a look at the following example:
package com.ray.ch11;public class Test {public static void main(String[] args) {Person man = new Man();man.sleep();man.run();// man.say();//error}}interface Person {public void sleep();public void run();}class Man implements Person {public void say() {}@Overridepublic void sleep() {}@Overridepublic void run() {}}
Our general code will be the same as above, define the interface directly, and then the interface points to the implemented class. In general, as shown above, the number of methods is reduced. However, let's modify the method as follows:
package com.ray.ch11;public class Test {public static void main(String[] args) {Person man = new Man();man.sleep();man.run();// man.say();//errorif (man instanceof Man) {Man man2 = (Man) man;man2.say();}}}interface Person {public void sleep();public void run();}class Man implements Person {public void say() {}@Overridepublic void sleep() {}@Overridepublic void run() {}}
We modified it and used the isInstanceOf method to perform a downward transformation. In this way, we can get all the methods in Man, or even the following code:
package com.ray.ch11;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Test {public static void main(String[] args) {try {Class manClass = Class.forName(com.ray.ch11.Man);Man man = (Man) manClass.newInstance();Method[] methods = man.getClass().getDeclaredMethods();for (Method method : methods) {System.out.println(method.getName());}Method sayMethod = manClass.newInstance().getClass().getDeclaredMethod(say);sayMethod.setAccessible(true);sayMethod.invoke(man);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}interface Person {public void sleep();public void run();}class Man implements Person {private void say() {System.out.println(method say);}@Overridepublic void sleep() {}@Overridepublic void run() {}}
Through the above Code, we directly call all methods in the class, including private methods.
This is fatal for encapsulation. Therefore, the server code we provide hides the class information, for example:
package com.ray.ch11;public class Test {public static Person makePerson() {return new Man();}public static void main(String[] args) {Person person = makePerson();}}interface Person {public void sleep();public void run();}class Man implements Person {private void say() {System.out.println(method say);}@Overridepublic void sleep() {}@Overridepublic void run() {}}
We use a method to implicitly implement the class, all of which are displayed in the form of interfaces, so as to avoid the above problems.
Summary: This section describes the interface and type information. You need to pay attention to the situation of directly calling classes across interfaces.