由为什么接口中只能定义静态常量引发的接口与抽象类的区别的问答
2013-12-07 17:31
411 查看
1、为什么必须是静态的:由于接口不能实例化,非静态成员只能使通过实例调用,所以必须定义为static静态的
2、为什么抽象类也不能被实例化,但抽象类里面可以定义非静态的:
由于子类与抽象类的关系中,子类继承(extends)抽象类,
java中,子类继承父类,子类实例化,首先要执行父类的构造器,所以抽象类里面有构造器,有构造器就有实例化,
只是这种实例化是比较特殊的实例化,也不能通过new创建实例,但是可以通过该特殊的实例化调用该抽象类里面的非静态字段,通过下面的代码可以发现
public abstract class D {
//可以被子类访问
protected int d2 = 1;
//获得抽象类D的实例
public D getInstance(){
//可以使用this调用非静态成员属性,说明有实例化过程,此处输出1
System.out.println(this.d2);
return this;
}
}
public class E extends D{
//子类重写父类属性,不会发生多态
private int d2 = 2;
public static void main(String[] args) {
E e = new E();
//java中的多态只发生在父类引用指向子类对象、子类重写父类的方法的情况下;
//如果同样是父类应用指向子类对象、子类重写父类的属性,则不会发生多态,调用的属性还是父类的属性
System.out.println(e.getInstance().d2);//输出1,返回的是父类D的实例,
}
}
子类与接口之间的关系式implements实现,子类实现接口,无需先执行接口的构造器,
所以接口中无需提供构造器(也没有语句块),也就没有实例化的过程,对于声明一个需要通过实例访问的非静态属性也就没有意义了
3、为什么要用final修饰为常量:
由于接口定义了一种协议、规范,所有子类都去实现该接口,如果将Field定义为static变量,不用final修饰,
所有实现类共享该Field,一个实现类修改该变量,所有实现类都将发生改变,所以必须用final修饰
4、为什么使用抽象类:
抽象类为子类提炼出公共的方法,并提供一个或几个抽象方法留给子类实现;
抽象类的设计体现了模板模式的设计思想,即抽象类公共的普通方法依赖一个抽象方法,而抽象方法则推迟到子类中实现细节
5、既然抽象类中既可以定义抽象方法,也可以定义普通方法,那为什么使用接口,而接口中只能定义抽象方法:
接口定义的一种协议、规范,体现的是规范也实现分离的松耦合的设计思想;
同时使用接口是implements实现,子类可以实现多个接口,却只能继承一个父类(java中的单继承机制);
所以子类继承一个完全是抽象方法的抽象类导致不能再继承其它类就没有什么意义了
ps:当然,抽象类与接口还有一些其它的区别,此处不一一详尽说明,上述阐述可能有不合理之处,不过希望给相关困惑读者一点思路
2、为什么抽象类也不能被实例化,但抽象类里面可以定义非静态的:
由于子类与抽象类的关系中,子类继承(extends)抽象类,
java中,子类继承父类,子类实例化,首先要执行父类的构造器,所以抽象类里面有构造器,有构造器就有实例化,
只是这种实例化是比较特殊的实例化,也不能通过new创建实例,但是可以通过该特殊的实例化调用该抽象类里面的非静态字段,通过下面的代码可以发现
public abstract class D {
//可以被子类访问
protected int d2 = 1;
//获得抽象类D的实例
public D getInstance(){
//可以使用this调用非静态成员属性,说明有实例化过程,此处输出1
System.out.println(this.d2);
return this;
}
}
public class E extends D{
//子类重写父类属性,不会发生多态
private int d2 = 2;
public static void main(String[] args) {
E e = new E();
//java中的多态只发生在父类引用指向子类对象、子类重写父类的方法的情况下;
//如果同样是父类应用指向子类对象、子类重写父类的属性,则不会发生多态,调用的属性还是父类的属性
System.out.println(e.getInstance().d2);//输出1,返回的是父类D的实例,
}
}
子类与接口之间的关系式implements实现,子类实现接口,无需先执行接口的构造器,
所以接口中无需提供构造器(也没有语句块),也就没有实例化的过程,对于声明一个需要通过实例访问的非静态属性也就没有意义了
3、为什么要用final修饰为常量:
由于接口定义了一种协议、规范,所有子类都去实现该接口,如果将Field定义为static变量,不用final修饰,
所有实现类共享该Field,一个实现类修改该变量,所有实现类都将发生改变,所以必须用final修饰
4、为什么使用抽象类:
抽象类为子类提炼出公共的方法,并提供一个或几个抽象方法留给子类实现;
抽象类的设计体现了模板模式的设计思想,即抽象类公共的普通方法依赖一个抽象方法,而抽象方法则推迟到子类中实现细节
5、既然抽象类中既可以定义抽象方法,也可以定义普通方法,那为什么使用接口,而接口中只能定义抽象方法:
接口定义的一种协议、规范,体现的是规范也实现分离的松耦合的设计思想;
同时使用接口是implements实现,子类可以实现多个接口,却只能继承一个父类(java中的单继承机制);
所以子类继承一个完全是抽象方法的抽象类导致不能再继承其它类就没有什么意义了
ps:当然,抽象类与接口还有一些其它的区别,此处不一一详尽说明,上述阐述可能有不合理之处,不过希望给相关困惑读者一点思路
相关文章推荐
- 通过类字面常量解释接口常量为什么只能定义为static final,类加载过程---Thinking in java
- 为什么接口中只能定义常量?
- 通过类字面常量解释接口常量为什么只能定义为static final,类加载过程---Thinking in java
- java接口为什么只能定义常量
- 通过类字面常量解释接口常量为什么只能定义为static final,类加载过程---Thinking in java
- 浅谈Java接口中为什么只能定义常量
- asp.net 中类,继承,抽象类,接口的定义方法?还有区别是什么?
- .Net面试基础问答:抽象类和接口的区别?
- 抽象类和接口的区别、为什么用抽象类。
- 抽象类和接口的区别、为什么用抽象类。
- 抽象类可以定义常量,接口中不可以定义常量
- 抽象类和接口的区别、为什么用抽象类。
- java 接口的定义,使用及和抽象类的区别
- JavaSE8基础 接口的成员变量只能是静态的常量
- 通过反射,将datatable转换为List集合(反射读取实体类的属性,并赋值),通过接口来实现MySql和MsSql数据的切换(二层反射),静态构造函数,抽象类和接口的区别
- 为什么 接口只用于定义类型,不应该使用常量接口 ?
- 接口中定义的变量为什么是常量
- 抽象类与接口的区别……静态方法与实例方法的区别
- 抽象类与接口的定义与区别
- 抽象类与接口的区别……静态方法与实例方法的区别