您的位置:首页 > 编程语言 > Java开发

从头认识java-12.6 接口与类型信息(怎么绕过接口直接调用类的所有方法)

2015-12-10 08:49 525 查看
这一章节我们来讨论一下接口与类型信息。
在之前的章节里面我们提到接口,父类引用子类对象,然后把方法给缩窄了,但是我们这一章节学习到反射,这个约束就变得没有那么严格。
我们来看看下面的例子:
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() {
}

@Override
public void sleep() {
}

@Override
public void run() {
}
}
我们一般的代码就会向上面一样,直接定义接口,然后接口指向实现的类。一般的情况就像上面一样,方法给变少了。但是,我们修改一下方法:
package com.ray.ch11;

public class Test {
public static void main(String[] args) {
Person man = new Man();
man.sleep();
man.run();
// man.say();//error
if (man instanceof Man) {
Man man2 = (Man) man;
man2.say();
}
}
}

interface Person {

public void sleep();

public void run();
}

class Man implements Person {
public void say() {
}

@Override
public void sleep() {
}

@Override
public void run() {
}
}
我们修改了一下,通过isInstanceOf方法,来向下转型,这样我们就可以得到Man里面所有的方法,甚至是下面的代码:
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");
}

@Override
public void sleep() {
}

@Override
public void run() {
}
}通过上面的代码,我们直接调用类里面所有的方法,包括私有方法。
这个对于封装来说是比较致命的,因此,我们提供的服务端代码一般都隐藏了类的信息,例如:
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");
}

@Override
public void sleep() {
}

@Override
public void run() {
}
}
我们通过一个方法隐含了类的实现,全部是以接口的形式对外展现,这样就可以避免了上面的一些问题。

总结:这一章节主要讲述了接口与类型信息的内容,需要注意跨过接口直接调用类的情况。

这一章节就到这里,谢谢。
-----------------------------------
目录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java