抽象类
1、抽象类基本概念
类继承的主要作用在于可以扩充已有类的功能,但是对于之前的继承操作而言会发现,子类可以由自己选择任意来决定是否要重写某一个方法。
这个时候父类无法对子类作出强制约定(强制性必须重写某些方法),这种情况下,往往不会采用类的继承(在实际开发之中,一般不会出现继承一个完善的类,可以直接使用的类)而是必须要继承抽象类,在以后进行父类(SuperClass)设计的时候优先考虑的是抽象类
抽象类基本定义:
抽象类的主要作用在于对子类中重写方法进行约定,在抽象类里面可以去定义一些抽象方法以实现这样的约定,抽象方法指使用了abstract关键字定义的并且没有提供方法体的方法,而抽象方法所在的类必须使用abstract关键字来进行定义
在普通类的基础上追加抽象方法就是抽象类
abstract class Message{ //抽象类
private String type ;
public abstract String getConnctInfo() ; //抽象方法
public void setType(String type ){
this.type = type ;
}
public String getType(){
return type ;
}
}
当一个抽象类定义完成之后(切记:“抽象类不是完整的类”),如果要使用抽象类,需要按照以下方法执行:
- 抽象类必须提供有子类,子类使用extends继承一个抽象类
- 抽象类的子类(不是抽象类)一定要重写抽象类中的全部抽象方法
- 抽象类的对象实例化可以利用对象多态性通过子类 向上转型 的方式完成
public class JavaDemo{
public static void main(String [] args){
Message message = new DatabaseMessage () ;
message.setType("信息") ;
System.out.println(message.getConnctInfo()) ;
System.out.println(message.getType()) ;
}
}
abstract class Message{
private String type ;
public abstract String getConnctInfo() ;
public void setType(String type ){
this.type = type ;
}
public String getType(){
return type ;
}
}
class DatabaseMessage extends Message{
public String getConnctInfo(){
return "数据库连接信息" ;
}
}
从整体上来讲,抽象类只是比普通方法增加了抽象方法以及对子类的强制性的重写要求而已,其他的使用过程和传统的类继承是完全相同的。
对于抽象类使用的几点意见:
- 抽象类使用很大程度上有一个核心的问题:抽象类自己无法直接实例化
- 抽象类之中主要的目的是进行过渡操作使用,所以当你使用抽象类进行开发的时候,往往都是在你的设计中需要解决类继承问题时所带来的的代码重复处理
2、抽象类的应用
抽象类的本质上就是属于一个加强型的类,那么对于类已经清楚了,可以描述一切有关的现实事物
通过分析可以知道,抽象类的设计应该是比类更高一层的定义
public class JavaDemo{
public static void main(String [] args){
Action robotAction = new Robot() ;
Action personAction = new Person() ;
Action pigAction = new Pig() ;
System.out.println("-------------------机器人的行为-------------------") ;
robotAction.command(Action.SLEEP) ;
robotAction.command(Action.WORK) ;
System.out.println("--------------------人类的行为-------------------") ;
personAction.command(Action.SLEEP + Action.EAT + Action.WORK) ;
System.out.println("---------------------猪的行为-------------------") ;
pigAction.work() ;
pigAction.eat() ;
pigAction.sleep() ;
}
}
abstract class Action{
public static final int EAT = 1 ;
public static final int SLEEP = 5 ;
public static final int WORK = 10 ;
public void command(int code){
switch(code){
case EAT : {
this.eat() ;
break ;
}
case SLEEP : {
this.sleep() ;
break ;
}
case WORK : {
this.work() ;
break ;
}
case EAT + SLEEP + WORK : {
this.eat() ;
this.sleep() ;
this.work() ;
break ;
}
}
}
public abstract void eat() ;
public abstract void sleep() ;
public abstract void work() ;
}
class Robot extends Action{
public void eat() {
System.out.println("机器人需要接通电源充电") ;
}
public void sleep() {}
public void work() {
System.out.println("机器人按照固定的套路进行工作") ;
}
}
class Person extends Action{
public void eat() {
System.out.println("饿的时候安静的坐下吃饭") ;
}
public void sleep(){
System.out.println("安静的躺下,慢慢的睡着,然后做着美丽的梦") ;
}
public void work(){
System.out.println("人类是高级脑类动物,是有方法的工作") ;
}
}
class Pig extends Action{
public void eat(){
System.out.println("吃食槽中人类给予的饭") ;
}
public void sleep(){
System.out.println("倒地直接就睡") ;
}
public void work(){}
}
现在的程序已经完整的实现了一个行为的抽象处理,但是也需要做出一点点思考。现在定义的Action父类主要的目的:
- 对所有行为规范进行统一处理
抽象类最大的好处是对子类方法的统一管理,还可以自身提供有一些普通方法并且这些普通方法可以调用抽象方法,这些抽象方法必须有子类提供子类实现的时候才会生效
3、抽象类的相关说明
抽象类是一个重要的面向对象设计的结构,对于抽象类使用的时候需要注意以下几点问题:
- 在定义抽象类的时候绝对不能够使用 final 关键字来进行定义,因为抽象类必须有子类,而 final 定义的类是不能够有子类的
- 抽象类是作为一个普通类的加强版出现的(抽象类的组成就是在普通类的基础上扩展而来的,只是追加了抽象方法),既然是在普通类的基础上扩展的,那么普通类之中就可以定义属性和方法,那么这些属性一定是要求进行内存开辟的
因此在抽象类中是可以提供构造方法的,并且子类也一定会按照子类对象的实例化原则进行父类构造调用。 - 抽象类中允许没有抽象方法,但是即便没有抽象方法,也无法直接使用关键字 new 来直接实例化抽象类对象,必须依靠子类对象完成
- 抽象类中可以提供static方法,并且该方法不受抽象类对象的局限
public class JavaDemo{
public static void main(String [] args){
Message message = Message.getInstance() ;
System.out.println(message.getInfo()) ;
}
}
abstract class Message{
public abstract String getInfo() ;
public static Message getInstance(){
return new DatabaseMessage() ;
}
}
class DatabaseMessage extends Message{
public String getInfo(){
return "数据库连接信息" ;
}
}
static 方法永远不受到实例化对象或结构的限制,永远可以直接通过类名称进行调用