1.何为抽象类
抽象类的声明与普通类相比,就多了一个abstract关键词。
抽象类中的方法同接口中的方法一样,没有方法体。
抽象类中可以有抽象方法,也可以没有抽象方法,但是有抽象方法存在的类必须是抽象类。
如果一个普通类作为父类,那么他的子类会重写父类中的方法;但是如果一个抽象类中的抽象方法被子类实现,那么该子类是实现父类中的抽象方法
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();
}
}
总结:
系统的来说,抽象类中既可以有自己特有的方法,也可以有供子类自己实现的方法。
因为面向对象的多态特性,抽象类中的特有的方法可以供继承该类的所有子类调用,所以也就成了父类一劳,所有子类永益的方法。
抽象类与接口的区别:
1、概念不一样。接口是对动作的抽象,抽象类是对本质的抽象。
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它。
所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。
2、使用不一样:
a.抽象类 和 接口 都是用来抽象具体对象的. 但是接口的抽象级别最高
b.抽象类可以有具体的方法 和属性, 接口只能有抽象方法和不可变常量
c.抽象类主要用来抽象类别,接口主要用来抽象功能.
d.抽象类中,且不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。
e.接口是设计的结果 ,抽象类是重构的结果
3、使用方向:当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
注意:抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。
关于抽象类的使用特点:
1.抽象类不能有对象,(不能用new此关键字来创建抽象类的对象);
2.有抽象方法的类一定是抽象类,但是抽象类中不一定有抽象方法;
3.抽象类中的抽象方法必须在子类中被重写。