Java中提供了抽象类还有接口,开发中如何去选择呢?
这道题想考察什么?
Java是面向对象编程的,抽象是它的一大特征,而体现这个特征的就是抽象类与接口。抽象类与接口某些情况下都能够互相替代,但是如果真的都能够互相替代,那Java为何会设计出抽象与接口的概念?这就需要面试者能够掌握两者的区别。
考察的知识点
OOP(面向对象)编程思想,抽象与接口的区别与应用场景;
考生应该如何回答
抽象类的设计目的,是代码复用;接口的设计目的,是对类的行为进行约束。
- 当需要表示is-a的关系,并且需要代码复用时用抽象类
- 当需要表示has-a的关系,可以使用接口
比如狗具有睡觉和吃饭方法,我们可以使用接口定义:
public interface Dog {
public void sleep();
public void eat();
}
但是我们发现如果采用接口,就需要让每个派生类都实现一次sleep方法。此时为了完成对sleep方法的复用,我们可以选择采用抽象类来定义:
public abstract class Dog {
public void sleep(){
//......
}
public abstract void eat();
}
但是如果我们训练,让狗拥有一项技能——握手,怎么添加这个行为? 将握手方法写入抽象类中,但是这会导致所有的狗都能够握手。
握手是训练出来的,是对狗的一种扩展。所以这时候我们需要单独定义握手这种行为。这种行为是否可以采用抽象类来定义呢?
public abstract Handshake{
abstract void doHandshake();
}
如果采用抽象类定义握手,那我们现在需要创建一类能够握手的狗怎么办?
public class HandShakeDog extends Dog //,Handshake
大家都知道在Java中不能多继承,这是因为多继承存在二义性问题。
二义性问题:一个类如果能够继承多个父类,那么如果其中父类A与父类B具有相同的方法,当调用这个方法时会调用哪个父类的方法呢?
所以此时,我们就需要使用接口来定义握手行为:
public interface Handshake{
void doHandshake();
}
public class HandShakeDog extends Dog implements Handshake
不是所有的狗都会握手,也不止狗会握手。我们可以同样训练猫,让猫也具备握手的技能,那么猫Cat类,同样能够实现此接口,这就是"has-a"的关系。
抽象类强调从属关系,接口强调功能,除了使用场景的不同之外,在定义中的不同则是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dknNlkNt-1685672050623)(images\接口与抽象区别.webp)]
重载和重写是什么意思,区别是什么?
这道题想考察什么?
Java基础
考察的知识点
面向对象多态的基础概念
考生应该如何回答
重写(Override)
重写就是重新写的意思,当父类中的方法对于子类来说不适用或者需要扩展增强时,子类可以对从父类中继承来的方法进行重写。
比如Activity是Android开发中四大组件之一。在Activity中存在各种声明周期方法:onCreate、onStart …等等。而我们应用中需要使用Activity来展示UI,那么我们会需要编写自己的类继承自Activity。
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
在上述代码中,onCreate就是被我们重写的Activity中定义方法。我们在onCreate增加了setContentView
的调用,完成了对超类Activity中对应方法的修改与扩展。
重载(Overload)
重载则是在同一个类中,允许存在多个同名方法,只要它们的参数列表不同即可。比如在Android开发中,我们会使用LayoutInflater的inflate方法加载布局,inflate方法存在多个定义,其中包括两个参数的,与三个参数的:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
//......
}
可以看到在两个参数的inflate方法中,会为我们调起三个参数的inflate方法,而定义第一个inflate方法的目的就是为了提供默认的attachToRoot
参数值。因为Java中无法定义方法参数默认值,所以我们经常使用重载达成此目的。
更多面试题详解可以扫描二维码免费领取!