JAVA 接口问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 接口问题相关的知识,希望对你有一定的参考价值。

Cat c = new Cat();
Pet p = new Cat();

其中Pet是接口,Cat是实现了Pet接口的类。
以上两者在实现类功能上有什麽不同?

设Pet为接口,有一个接口方法: speak()//说话发声
类Cat 类Dog 都实现该Pet接口
静态类PetManager为宠物管理类。它有方法 public static Pet getPet(参数:声音类型),访方法能生成(制造出)一个Dog或者Cat

其中Cat 对speak的实现为: public void speak() “喵一声”
其中Dog 对speak的实现为: public void speak()(“汪一声”)

有个客户它想听一声猫叫,那么该客户就可以Cat c = new Cat(); c.speak();
有个客户它想听一声狗叫,那么该客户就可以 Dog d=new Dog(); d.speak();

可是很多情况下客户只想听个宠物叫一声,不管它是猫还是狗,只要能解解闷就行,那么就可以 :
Pet p; p= PetMager.getPet(); p.speak();
这时候前面的Cat c 和Dog d 就都不行了。因为 cat不能叫汪一声, dog不能叫喵一声; 随着时间变化,客户可能还想听牛叫,马叫,猪叫....
这个时候如果用写死的那个Cat 或Dog 客户端的代码就无法表现了。 如果要实现,就必须升级客户端的代码,如果这种产品己经卖了几千万份出去,那就会有几千万人排队来厂家门口升级他们的产品。
我们需要做到尽量让客户手上的产品少升级以方便用户。所以,我们不要太具体地指定 : Pet p;
至于p从哪里来,我们可以从公司的营销模式逻辑来调整,也就是getPet()方法。
以后,客户想听更多的声音,只要公司内部进行调整,把新产品加到目录就可以了。客户端不需做任何改变;客户想听什么声音都可以;

现在来实现PetManager的getPet():
public static Pet getPet(参数:声音类型)
if 猫: return new Cat();
if 狗: return new Dog();
if 猪: return new pig();
if 牛: .....
..............


在这种情况下 getPet()称之为Pet实例的工厂方法!它是工厂,由它来生产Pet。程序逻辑根据客户的需求来产生具体的宠物实例。客户不需要关心这个宠物到底是怎么产生的。
这样的程序称之为对客户透明性;
我们如果对工厂再进行一些高级拓展就可以向20多种设计模式发展,如抽象工厂、工厂的工厂等等....

现在总结: 在现实生活中,客户的需求是变化的,不确定的,所以我们需要灵活的机制来满足客户的需要。客户今天可能想要猫,明天可能想要狗,或者他只是想随便找个宠物来玩一玩。所以我们不能把写死了就是猫,改天他想要狗了我们只需把getPet方法里的逻辑改改就行了,而不需要去改客户的需求

接口和抽像类是java面向对象的精华部分,一定要弄明白!否则java就白学了!
而且在编程时尽量做到以下原则:
1。面向抽像编程,少用具体;
2。多用类的接口编程,少用类的继承! 大陆的书把类的继承讲很大的篇幅,给人一种很深的误解,可能认为继承是最重要的;

另外再讲一个例子:
1。假设电影是一个接口(电影是抽象的名词);
2。客户想看最新的电影(需要一个具体的电影名)
3.《色戒》,《赤壁》是具体的影片,实现了电影这个接口,都可以被影院放出来;
4。电影院的服务宗旨是:放影片(抽象)!绝不能说成宗旨是放《色戒》(具体)否则下次电影院就放不出赤壁了也没有客户愿意来看电影了。
参考技术A 当你保证你的Cat类里的方法在以后的应用过程中永远不发生变化的话,那么用接口还是用具体类都可以。
用接口的好处就是,当你以后Cat类里的方法要改变的时候,你调到的方法永远符合你现在Pet接口的规范。
就像你加入现在用List l = new ArrayList();一样,以后你要是打算不用ArrayList了而换成LinkedList了,如果你不用接口的话就出问题了。
参考技术B Pet p = new Cat();
其实是生成了一个Cat类的对象(无名对象),然后将该对象的引用赋给了p.
然后当p调用被Cat类实现的方法时,
其实是通知该Cat类的对象(无名对象)调用Cat类中实现的方法.

故,两者没有区别,最终实行方法的还是一个Cat类的对象. 硬要说的话,就是接口回调时多了个通知实现类的对象的过程吧.

以上,个人理解..
参考技术C 第一个语句就是一般的创建一个对象
第二个语句是利用对象的上转型对象,就是所谓的接口回调,就是把实现接口的类所创建的对象赋值给接口的对象,让其去调用类中的方法,完成相应的功能
参考技术D 不同在于看待问题的视角,

就像你在你母亲面前是个乖孩子(接口),在老婆面前是好老公(接口)一样,其实只有一个你(实际对象),那是你的本质。
第5个回答  2008-12-23 c自己定义的方法p找不到.

Java 接口扩展了 java.util 包中的接口

【中文标题】Java 接口扩展了 java.util 包中的接口【英文标题】:Java interface extends interface in the java.util package 【发布时间】:2012-10-23 16:56:06 【问题描述】:

众所周知,接口可以扩展Java中的接口。我有一个问题,如果接口B扩展接口A,B不需要实现A中定义的方法。但是在java.util包中,List接口扩展了Collection接口,它实现了Collection方法,这些方法也只需声明方法即可。

为什么要这样做,还有更好的做法吗?在子接口中实现方法有什么区别吗?

【问题讨论】:

List 中重新定义了 Collection 中的什么方法?你能举个例子吗? List 中实现了哪些方法? @Vikdor:所有这些...... ***.com/questions/563952/…的可能重复 【参考方案1】:

重写方法,除了提供/替换方法实现之外,还允许提供更具体的 javadoc,并缩小返回类型。

例如,Collection.iterator() 指定为:

返回此集合中元素的迭代器。没有 关于元素返回顺序的保证 (除非这个集合是某个类的实例,它提供了 保证)。

List.iterator()

指定

以正确的顺序返回此列表中元素的迭代器。

【讨论】:

【参考方案2】:

除了声明之外,我在 java.util.List 中没有看到任何实现。相反,List 的 javadocs 说,

List 界面添加了额外的规定,超出 在 Collection 界面中指定的那些,在 迭代器的合约,添加,删除, equals 和 hashCode 方法。声明为 为方便起见,此处还包括其他继承的方法。

【讨论】:

【参考方案3】:

接口列表不实现集合的方法,因为接口只是不能实现方法,它们只是声明它们。接口就像一个 100% 的抽象类:所有方法必须是抽象方法。

您的困惑可能来自实现接口的抽象类:这些类不能实现接口的方法(尽管被允许),只有第一个具体类必须。

【讨论】:

【参考方案4】:

Java 中的接口是完全抽象的。他们不能有任何实现。

重新声明方法与实现方法不同。并且重新声明一个方法没有任何意义(如果方法签名完全相同),因为一个接口扩展另一个接口的目的是添加一些更具体的方法声明,而不仅仅是重新声明现有的方法。


编辑


正如@Arham's和@meriton's回答中指出的那样,重新声明的目的是根据子接口重新指定方法。因此,对于访问底层集合的客户端代码,重新声明的方法将有一个单独的更具体的规范,而不是超级接口中更通用的规范。

【讨论】:

显然 Java API 的设计者不同意你的第二段。 @meriton:你能告诉我你想告诉我什么吗? :) 嗯,他们确实List 中重新声明了Collection 的所有方法。如果他们认为这样做没有任何意义,我怀疑他们会这样做...... 他们只是为了方便而重新声明了它们。它还有助于重新定义该特定方法的 javadocs。 @meriton:我现在明白了,它有助于从子界面的角度重新规范行为。 :)

以上是关于JAVA 接口问题的主要内容,如果未能解决你的问题,请参考以下文章

请问Java中接口与Object类的问题

java实现多个接口问题,急求大神啊

关于java跨项目调用接口的问题

java接口获取数据乱码问题 !!!

Java14-java语法基础(十三)接口

java中接口可以实现多个接口吗