接口引用指向实现类的对象

接口 f 方法 f 实现类 g 实现接口方法 自定义方法 g
F f= new g();
f.g()不到,如何解释
向上转型为什么会丢掉g();



public interface F {
	public void f();
}

public class G implements F {
	public static void main(String []args) {
		F g=new G();
		g.g(); //这个方法看不到呢,如何解释
	}
	
	public void g(){
	
	}
	
	public void f(){
		// TODO Auto-generated method stub
	}
}

接口G实现了F
但是你是把一个G的实例,送给了F的引用,向上转型的时候丢失掉了g();
如果你想 g.g();调用成功的话,用强制转型 ((G)g).g();
补充:
首先类G是实现F的!看的普通一点,可以看成G是继承F的。这么理解下。
既然G是实现(继承)F的,那么F中的方法,自然被继承到了。但是G中可以定义自己的方法。这是没有疑问的。
JAVA中的多态机制却允许基类的引用指向子类的实例。因为基类中没有子类的方法,所以在这个过程中,子类的方法被扔掉。
同理,用到这个地方。 G中g()是G自己有的,F没有,那么向上(基类)转型过程中,g()被扔掉了。这就是所谓的向上转型丢失某些方法;
因为不丢掉的话,那就意味着,子类能给父类增添方法,这显然是不合乎道理的!!父类的方法只有自己增加

经常见
List<?> list= new ArrayList<?>
Map<?,?> map = new HashMap<?,?>

但是发现list只是ArrayList的接口不是它的父类 ,不是父类引用指向子类对象

如果是应该是AbstractLIst ablist= new ArraryList(); 或者直接写为ArrayList<?> list= new ArrayList<?>

为什么要用接口引用指向实现类的对象

这种写法其实Java多态的表现形式

多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
List list;是在栈区开辟一个空间放list引用,并没有创建对象所以不知道ArrayList还是LinkedList当你list= new ArrayList(); 就创建了ArrayList对象。并且把开始创建的list引用指向这个对象ArrayList和LinkedList都是List的实现类。

为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?

问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类呢?,这时你只要改变这一行就行了:List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。 ,如果没有特别需求的话,最好使用List list = new LinkedList(); ,便于程序代码的重构. 这就是面向接口编程的好处

注意事项

list只能使用ArrayList中已经实现了的List接口中的方法,ArrayList中那些自己的、没有在List接口定义的方法是不可以被访问到的

list.add()其实是List接口的方法

但是调用ArrayList的方法如 clone()方法是调用不到的

接口的灵活性就在于“规定一个类必须做什么,而不管你如何做”。我们可以定义一个接口类型的引用变量来引用实现接口的类的实例,当这个引用调用方法时,它会根据实际引用的类的实例来判断具体调用哪个方法,这和上述的超类对象引用访问子类对象的机制相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值