详述java中的抽象类,与普通类,接口的区别
目录
如果是一个新手程序员的话,那么对抽象类可以说是只知道其存在,但不知道其真正的作用,所以在工程中很少用抽象类来实现代码。
但是抽象类在某些时候的功能很强大,可以保证子类中百分百实现父类中的方法——普通类的弊端、消除子类的冗余代码——接口的弊端(敲黑板,这些是重点)
那么今天我来简单叙述一下抽象类的优势,并且拿来有普通类和接口比较一下
1.何为抽象类
- 抽象类的声明与普通类相比,就多了一个abstract关键词。
- 抽象类中的方法同接口中的方法一样,没有body体。
- 抽象类中可以有抽象方法,也可以没有抽象方法,但是有抽象方法存在的类必须是抽象类。
- 如果一个普通类作为父类,那么他的子类会重写父类中的方法;但是如果一个抽象类中的抽象方法被子类实现,那么该子类是实现父类中的抽象方法
2.基础知识支持:多态
概念:父类或者是接口的引用,可以指向子类或者是实现类的对象。
那么该对象既可以调用子类/实现类中的方法,也可以调用父类中的方法
3.普通类举例
1.声明一个普通父类,该父类中有一个其所有子类同化的方法,和一个所有子类可以个性化的方法
package com.util;
public class Parent {
/**
* @Description 所以子类同化的方法,子类中无须重写
* @author lvyingliang
* @date 2019年2月15日
* @return_type void
*/
public void parentHabits(){
System.out.println("I can sleep.");
}
/**
* @Description 当子类实现该父类时,生成的子类中不会自动添加需要重写的方法,需要人为对照父类中的方法名来实现,麻烦且不安全(方法名易照搬错误)
* @author lvxiaobu
* @date 2019年2月15日
* @return_type void
*/
public void sonHabit(){
System.out.println("There will be overrided by son.");
}
}
2.声明一个该父类的子类,对个性化方法sonHabit进行重写
package com.util;
public class Son extends Parent {
/**
* @Description 子类中的方法不会与父类关联,所以在子类中重写方法时,需要再次打开父类代码,参照并格外注意重写方法名的一致性
* @author lvxiaobu
* @date 2019年2月15日
* @return_type void
*/
public void sonHatbit(){
System.out.println(" I am a fish , and I just can swim in the sea .");
}
}
3.输出结果:
package com.util;
public class Test {
public static void main(String[] args) {
//普通父类
Parent p = new Son();
p.parentHabits();
p.sonHabit();
//接口
// InterfaceParent p = new InterfaceSon();
// p.parentHabits();
// p.sonHabit();
//抽象父类
// AbstractParent son = new AbstractSon();
// son.parentHabits();
// son.sonHabit();
}
}
//执行结果
I can sleep.
I am a fish , and I just can swim in the sea .
4.思考:
当子类需要重写父类中的某一个方法时,需要格外注意父类中被重写的方法名是否与子类中重写的方法名一致,这一点比较麻烦。
有没有一种可能,就像实现类实现接口那样(那样是哪样?可以看一下下面的接口例子),让程序帮我们自动关联父类中的需要重写的方法,保证子类中重写的方法百分百是父类中的方法呢?
答案当然是有。
4.接口实现举例:
1.声明一个接口,该接口中有例1中的同化方法和个性方法供子类实现
package com.util;
public interface InterfaceParent {
/**
* @Description 弊端:如果实现该接口的所有实现类中的parentHabits一样,那么就需要在各个实现类中出现大量重复的代码
* @author lvxiaobu
* @date 2019年2月15日
* @return_type void
*/
public void parentHabits();
public void sonHabit();
}
2.声明一个实现类,实现上述中的全部方法
package com.util;
public class InterfaceSon implements InterfaceParent {
@Override
public void parentHabits() {
System.out.println("I can sleep.");//如果还有其他子类,此方法需要重复实现
}
@Override
public void sonHabit() {
System.out.println(" I am a fish , and I just can swim in the sea .");
}
}
3.输出结果
package com.util;
public class Test {
public static void main(String[] args) {
//普通父类
// Parent p = new Son();
// p.parentHabits();
// p.sonHabit();
//接口
InterfaceParent p = new InterfaceSon();
p.parentHabits();
p.sonHabit();
//抽象父类
// AbstractParent son = new AbstractSon();
// son.parentHabits();
// son.sonHabit();
}
}
4.思考:
如果该接口不止一个 实现类,那么所有的实现类都需要将接口中的两个方法全部实现。但是因为第一个parentHabits()方法是所有子类同化的方法,所以这就会在多个子类中产生大量相同的代码。
那么有没有一种可能,将所有子类的同化代码在接口中统一实现,实现类中只实现自己的个性化方法呢?
答案当然也是有。
那么下面就有请我们的抽象类登场。
5.抽象类举例
1.创建一个父类抽象类,需要注意几点
1.将该类下所有子类的同化方法声明为普通方法,直接实现。这样,子类就无需再重复实现该同化方法了,减少代码
2.将子类的个性化方法声明为抽象方法。这样,当子类继承该父类时,会提示需要实现的方法,保证百分百实现父类中的该方法。
package com.util;
public abstract class AbstractParent {
/**
* @Description 该父类下所有子类的共同方法
* @author lvxiaobu
* @date 2019年2月15日
* @return_type void
*/
public void parentHabits(){
System.out.println("I can sleep.");
}
/**
* @Description 该父类下所有子类的个性方法供子类自己实现
* @author lvxiaobu
* @date 2019年2月15日
* @return_type void
*/
public abstract void sonHabit();
}
2.声明一个子类,继承该抽象类,并且实现自己的个性化方法sonHabit()
package com.util;
public class AbstractSon extends AbstractParent {
@Override
public void sonHabit() {
System.out.println(" I am a fish , and I just can swim in the sea .");
}
}
3.测试结果
package com.util;
public class Test {
public static void main(String[] args) {
//普通父类
// Parent p = new Son();
// p.parentHabits();
// p.sonHabit();
//接口
// InterfaceParent p = new InterfaceSon();
// p.parentHabits();
// p.sonHabit();
//抽象父类
AbstractParent son = new AbstractSon();
son.parentHabits();
son.sonHabit();
}
}
总结:
系统的来说,抽象类中既可以有自己特有的方法,也可以有供子类自己实现的方法。
因为面向对象的多态特性,抽象类中的特有的方法可以供继承该类的所有子类调用,所以也就成了父类一劳,所有子类永益的方法。
如果有书写错误的地方,或者是有问题的地方请及时评论或者是私信我,以免误导个别萌新。
虽然我也是个萌新。
你好,我叫吕小布
下一篇: OpenCV 棋盘 相机标定 一