问一个简单的问题,接口

flyskytoday 2017-03-22 10:49:31
public interface Imy {
}

public class A implements Imy{
}

public class B extends A implements Imy{
}
// 问一下此时B继承了A,但又重复了一次接口Imy,会不会有潜在问题???
...全文
375 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sakura_BAI 2017-03-23
  • 打赏
  • 举报
回复
学习了,以前没有想过这个问题
CG国斌 2017-03-23
  • 打赏
  • 举报
回复
一个类可以实现多个接口,接口中定义的都是抽象的东西, 没有具体实现,因此就算两个接口中定义了相同的变量或者方法也是没有问题的。
heqifan19891115 2017-03-22
  • 打赏
  • 举报
回复
学习了,非常感谢
o枫叶o 2017-03-22
  • 打赏
  • 举报
回复
接口除了有规定要实现哪些方法之外,一个很重要的作用就是起标识作用。 你可以看一下RandomAccess接口,里面一个方法都没有,它的作用就是标识类的某些功能或者某些特性,你可以理解为注释。 接口最本质的作用就是告诉程序员这个类可以干什么,这样一来,虽然没见过这个类,但通过接口就可以对这个类有一个本质的认识。 至于为什么要在子类里重复实现接口。试问,如果某个类上面有10层的继承,若只在第一层声明个接口,那不让人找疯了?
zs808 2017-03-22
  • 打赏
  • 举报
回复
不会有问题。 因为,B extend A的时候,其实就相当于 implements lmy了,你后面加不加implements lmy,其实是一个样的。 如果你不放心,就看看JDK里面的集合框架,里面几乎都是这么写:
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
如果你还不放心,可以尝试以下代码:
	public static interface Imy {
		public void hi();
	}

	public static class A implements Imy{
		@Override
		public void hi() {
		}
	}

	public static class B extends A implements Imy{
	}
	public static void main(String[] args) {
		A a = new A();
		a.hi();
		B b = new B();
		b.hi();
	}
然后对生成的App$Imy.class,App$A.class,App$B.class,App.class进行javap -c反编译,结果如下: App$Imy.class:

Compiled from "App.java"
public interface org.imzhs.learn.test.App$Imy{
public abstract void hi();

}
这个没什么,就是一个接口里面有个hi方法,该方法时抽象的(接口的方法默认都是抽象方法) App$A.class:

Compiled from "App.java"
public class org.imzhs.learn.test.App$A extends java.lang.Object implements org.imzhs.learn.test.App$Imy{
public org.imzhs.learn.test.App$A();
  Code:
   0:   aload_0
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
   4:   return

public void hi();
  Code:
   0:   return

}
这里可以看到,A里面实现了Imy的hi方法 App$B.class:

Compiled from "App.java"
Compiled from "App.java"
public class org.imzhs.learn.test.App$B extends org.imzhs.learn.test.App$A implements org.imzhs.learn.test.App$Imy{
public org.imzhs.learn.test.App$B();
  Code:
   0:   aload_0
   1:   invokespecial   #10; //Method org/imzhs/learn/test/App$A."<init>":()V
   4:   return

}
这里,继承了A,实现了Imy,但是B中并没有出现hi()方法,因为hi()方法已经在A中实现 App.class:

Compiled from "App.java"
public class org.imzhs.learn.test.App extends java.lang.Object{
public org.imzhs.learn.test.App();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #16; //class org/imzhs/learn/test/App$A
   3:   dup
   4:   invokespecial   #18; //Method org/imzhs/learn/test/App$A."<init>":()V
   7:   astore_1
   8:   aload_1
   9:   invokevirtual   #19; //Method org/imzhs/learn/test/App$A.hi:()V
   12:  new     #22; //class org/imzhs/learn/test/App$B
   15:  dup
   16:  invokespecial   #24; //Method org/imzhs/learn/test/App$B."<init>":()V
   19:  astore_2
   20:  aload_2
   21:  invokevirtual   #25; //Method org/imzhs/learn/test/App$B.hi:()V
   24:  return

}
可以看到,APP.java中的main()方法,对于A,B中hi()的调用全部都是通过invokevirtual 进行,而invokevirtual会从当前对象开始,由下到上寻找hi()的实现,所以最终找到的都是A中的hi()方法。 那么,我们把Class B改成:

public static class B extends A{
	}
此时,B生成的字节码为:

Compiled from "App.java"
public class org.imzhs.learn.test.App$B extends org.imzhs.learn.test.App$A{
public org.imzhs.learn.test.App$B();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method org/imzhs/learn/test/App$A."<init>":()V
   4:   return

}
可以看到,除了类头部发生一点改变,其它都没有变化,那么APP.Class呢?

Compiled from "App.java"
public class org.imzhs.learn.test.App extends java.lang.Object{
public org.imzhs.learn.test.App();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #16; //class org/imzhs/learn/test/App$A
   3:   dup
   4:   invokespecial   #18; //Method org/imzhs/learn/test/App$A."<init>":()V
   7:   astore_1
   8:   aload_1
   9:   invokevirtual   #19; //Method org/imzhs/learn/test/App$A.hi:()V
   12:  new     #22; //class org/imzhs/learn/test/App$B
   15:  dup
   16:  invokespecial   #24; //Method org/imzhs/learn/test/App$B."<init>":()V
   19:  astore_2
   20:  aload_2
   21:  invokevirtual   #25; //Method org/imzhs/learn/test/App$B.hi:()V
   24:  return

}
并没有任何变化。 ====== 总而言之,implements 是向下继承的,所以基类会默认实现父类的所有接口,基类加不加implements对实际的代码逻辑是没有影响的。
  • 打赏
  • 举报
回复
extends 上继承 因为他是一个简单的抽象
flyskytoday 2017-03-22
  • 打赏
  • 举报
回复
引用 1 楼 moguobiao 的回复:
不会有问题。
为什么这样没问题,有什么理由吗?
moguobiao 2017-03-22
  • 打赏
  • 举报
回复
不会有问题。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧