JAVA接口中对于字段会加上隐式的public,final,static,方法会加上public,abstract,
请问:
1,为什么必须是public的?protected不也行吗?既然接口主要是用来继承实现的,那么为什么protected不可以?
2,字段为什么必须是final和static的?
请大家指点,为什么这么设计,最好能举出反例,即如果不这么设计会出现什么问题。
谢谢!
请问:
1,为什么必须是public的?protected不也行吗?既然接口主要是用来继承实现的,那么为什么protected不可以?
2,字段为什么必须是final和static的?
请大家指点,为什么这么设计,最好能举出反例,即如果不这么设计会出现什么问题。
谢谢!
如果接口中的方法可以是protected:
package test.interface;
interface MyInterface {
protected void f();
}class A implements MyInterface {
public void f() {}
}package test.impl;
class B implements MyInterface {
public void f() {}
}package test;
public class Test {
public static void main(String[] args) {
MyInterface mi1 = new A();
MyInterface mi2 = new B();
mi1.f();//如果允许是protected那么这里就不行了,还能用多态吗?
mi2.f();//一样
}
}接口中的field如果可以不一样那还叫接口干什么??而只有static final才能保证一样。
太久没看Java了,说错了的话清大家见谅
2,变更默认加public static final表示静态的常量,这也是接囗的优点,如果你不想用这个,那你可以直接用接囗,那样变量/字段用什么修饰就看你自己了
Static:用来声明类中的全局类变量,相对于实例变量。如下:
public class StaticTest
{
int x=1; //实例变量
static int y=1; //全局变量
public StaticTest()
{
x++;
y++;
}
public static void main(String[] args)
{
StaticTest t1=new StaticTest(); //生成实例t1
StaticTest t2=new StaticTest(); //生成实例t2
System.out.println("t1.x="+t1.x); //输出实例t1中的变量x
System.out.println("t2.x="+t2.x); //输出实例t2中的变量x
//System.out.println("StaticTest.x="+StaticTest.x);//无法输出类StaticTest中的变量x
System.out.println("StaticTest.y="+StaticTest.y);//输出类StaticTest中的变量y
}
}
//执行后输出结果如下:
t1.x=2
t2.x=2
StaticTest.y=3
在上例中x为实例变量,y为全局变量。当生成StaticTest类的实例t1时系统为实例变量x、全局变量y初始化分配空间,并执行方法StaticTest();生成第二个实例t2时重新初始化x为1、全局变量y此时已经赋值为2,执行方法ststictest();实例变量无法由类直接引用,必须在生成实例后由实例进行引用。final:只用来修饰类及其的成员:变量、方法;final类无法继承、final变量无法修改、final方法无法重写。如下:
public final class FinalTest
{
final int i=10;
public FinalTest(){}
public final int getNumber()
{
i =20;//i无法被再次处世化
return i;
}
}
class FinalSub extends FinalTest{}//FinalTest无法被继承FinalSub
class FinalDemo
{
final int getNumber()
{
return 10;
}
}
class FinalDemoSub extends FinalDemo
{
int getNumber(){return 20;}//getNumber()无法重写
}Abstract:用来声明类为抽象方法类,被Abstract声明的类中至少有一个方法被Abstract声明为抽象方法并且抽象方法中没有实现内容。含有抽象方法的类必须被声明为抽象类。
抽象类无法创建对象,只能用来被继承,继承抽象类的子类必须重写所有父类中的抽象方法。如:
public abstract class Account
{
public abstract String getName();
.....
}InterFace:接口是抽象类的一个特例,接口中所有的方法必须为抽象方法,一个类可以实现多个接口,接口可以继承接口。
接口实现与继承实现:
接口实现区别与继承[或此形式的实现],但都可以upcasting + riit 实现多态
继承可以通过super关键字调用包括protected方法;请问接口可以有实例吗?当然不可以是protected方法接口的属性:根据接口的定义,需要避免具体的实现去修改接口的属性值;否则就是大逆不道
类的访问控制符只有public和默认两种,为了让所有类都能访问到当然要用public
2,字段为什么必须是final和static的?
接口不能被实例化,所以要用static修饰属性
如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为来修改属性.
变量默认被设成static final的才有用
总之,这是规定
2.字段如果不是static final,会被实现它的类所修改,违背了接口的目的。
你可以简单的将接口看作是是一种更加抽象的更加强的抽象类.接口的存在是有其显示意义的.举个例子:售货员和自动售货机,从继承的观点来看,二者应当属于不同的类,但是他们都能实现提供货物,收钱,找零钱的工作.就这一点来看,对顾客而言,售货员和自动售货机在功能上是相同的--他们由着统一的服务接口(提供货物,收钱,找零钱).
接口在下列面向对象编程的情况下非常有用:
1 声明其他类希望实现的方法.这使程序可以定义要调用的接口,但却由其他开发人员来实现.
2 声明对象的公共接口确隐藏其所属的类.这使对象不止一个实现能隐藏在协议的背后,防止用户使用未公开的方法.
3 获取没有层次关系的类自建的相似性.正如上面举的例子,某些类在大多数方面没有什么关系,但它们也许会为相似的外部组件提供相应的方法.接口在帮助这种关系正规化的同时保持了封装性.
由于上面提到的接口的用途,导致接口中的方法应当都是public的,(如果是其他形式的就失去了它的意义).又由于接口关注的是对象的行为,而非对象的属性(如果由共同的属性,则说明两个对象具有共同性,他们应当用抽象类来建立关系),因此接口中不能由任何形式的属性,只能由常量.且接口不代表类因此不能实例化,所以接口中的常量必须是静态的.
1,如果接口中有个方法,我希望它只在包内可见,但接口中的方法都隐式的加上public了,这种情况怎么办?
2,既然说接口不代表类因此不能实例化,所以接口中的常量必须是静态的.那么抽象类呢,它也不能实例化,为什么就可以有实例变量?
接口和抽象类的不同点有:
(1)抽象类可以有实例变量,而接口不能拥有实例变量,接口中的变量都是静态(static)的常量(final)。
(2)抽象类可以有非抽象方法,而接口只能有抽象方法。
java中,类与类之间是不能多继承的。java之所以禁止类与类之间的多继承是因为多继承有很大的缺点。
多继承虽然能使子类同时拥有多个父类的特征,但是其缺点也是很显著的,主要有两方面:
(1)如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。例如:
类ClassA:Java代码
public class ClassA {
protected int varSame = 0 ;
}
类ClassB:Java代码
public class ClassB {
protected int varSame = 1 ;
}
子类ClassC:(假设允许类与类之间多继承)Java代码
public class ClassC extends ClassA, ClassB {
public void printOut() {
System.out.println( super .varSame);
}
public static void main(String[] args) {
ClassC classC = new ClassC();
classC.printOut();
}
}
上面程序的运行结果会是什么呢?输出0还是1?
(2)如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。例如:
类ClassA:Java代码
public class ClassA {
public void printOut() {
System.out.println( 0 );
}
}
类ClassB: Java代码
public class ClassB {
public void printOut() {
System.out.println( 1 );
}
}
子类ClassC:(假设允许类与类之间多继承)Java代码
public class ClassC extends ClassA, ClassB {
public static void main(String[] args) {
ClassA classA = new ClassC();
classA.printOut(); // ------------------------- A行
ClassB classB = new ClassC();
classB.printOut(); // ------------------------- B行
ClassC classC = new ClassC();
classC.printOut(); //------------------------- C行
}
}
上面程序的运行结果会是什么呢?A、B、C三行的输出是0还是1?
正因为有以上的致命缺点,所以java中禁止一个类继承多个父类;但是幸运的是java提供了接口,并能通过接口的功能获得多继承的许多优点而又摒弃了类与类多继承的缺点。
java允许一个接口继承多个父接口,也允许一个类实现多个接口,而这样的多继承有上面提到的缺点马?
答案是没有,这是由接口的抽象性决定的。
正如前面介绍的,在接口中不能有实例变量,只能有静态的常量,不能有具体的方法(包含方法体),只能有抽象方法,因此也就摒弃了多继承的缺点。
1. 虽然接口中的方法必须是public,但接口本身可以是非public的,因此只要用户无法访问你的接口,就自然无法通过接口访问你的接口方法了。
2. 抽象类是类,不管它有多抽象,它也是类,不是接口,所以它允许拥有一个类能拥有的任何东西。其实,抽象类其实最终也是要实例化的,只不过这种实例化是隐含地发生的,从这个意义上说,抽象类和接口有着本质区别。
Java这样设计就是 取其精华,去其糟粕 是有历史原因的
抽象类与抽象接口之抽象接口
抽象类与抽象接口之两者区别
就应该是公有的不
若是protected那也是有限制的
只有公有的才可以最广范被别的类使用
原来一直对类和属性以及方法的修饰符分不清,现在明白了,如下:类的修饰符一般是public 或 默认的 friendly,但是运行时jvm会自动将friendly升级为public。而内部类则可以使用public,默认的friendly,protected,private,修饰。方法和属性的修饰符都可以用public,默认的friendly,protected,private,修饰。