java中的抽象类与方法

抽象类与方法的基本概念

抽象类

抽象类是指在普通类的结构里面增加的组成部分。在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象方法

是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。

基本语法与注意项

语法

假设我们有一个动物类,是抽象类,那么要加上关键字abstract,在里面定义一个跑的抽象方法,依然要加上abstract关键字。

public abstract class Animal {
    public abstract void run();
}

注意点 

  • 抽象方法是不能有方法体的,只能有方法签名。
  • 一个类中定义了抽象方法,这个类必须声明成抽象类,否则报错。

使用场景 

抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。

例如:

定义一个动物抽象类,里面定义一个跑的抽象方法。由于不同动物跑的速度或者姿势不同,所以在定义跑这个方法时,并不能写死,也就是明确定义出跑的怎么样。

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();
        dog.run();
        cat.run();
    }
}
public abstract class Animal {
    public abstract void run();
}
public class Dog extends Animal{
   public void run(){
       System.out.println("狗跑的更快");
    }
}
public class Cat extends Animal {
    public void run(){
        System.out.println("猫跑的快");
    }
}

输出结果:狗跑的更快
                  猫跑的快


项目案例

 

public class Test {
    public static void main(String[] args) {
        G_card c1 = new G_card();
        c1.setMoney(2000);
        c1.setName("张三");
        c1.pay(300);
        System.out.println("剩余:"+ c1.getMoney());
    }
}
public abstract class  Card {
    private String name;
    private double money;

    public abstract void pay(double money2);

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
}
public class G_card extends Card {
    public void pay(double money2) {

        System.out.println("您的卡余额为:" + getMoney());
        System.out.println("您消费金额为:" + money2);

        double rs = money2 * 0.8;
        System.out.println("您实际支付:" + rs);
        setMoney(getMoney() - rs);
    }
}

输出结果:

您卡余额为:2000.0
您消费金额为:300.0
您实际支付:240.0
剩余:1760.0

分析代码思路及目的

完全类似与前面提到的动物类的案例,在这个案例中,由于我们有两种不同种类的卡,卡的优惠力度各不相同,故在Card类里的消费方法并不能写死,这时就需要我们的抽象类了。


到这里不知道大伙有没有发现一个问题,不管是前面说到的animal案例和card案例,我们都没有创建其对象??二是创建他们子类的对象??

最重要的特征:

得到了抽象方法,但是去了创建对象的能力


模板方法模式

什么是模板方法模式?当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。

把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。模板方法中不能决定的功能定义成抽象方法让具体子类去实现。

项目案例:

假设我们不按照模板方法来写,那么在定义中学生和小学生两个类时,我们要分别写开头和结尾,由于开头结尾相同,故产生了屎山代码。

class Student_C {
    public void write(){
        // 开头
        System.out.println("\t\t\t\t《我的爸爸》");
        System.out.println("我的爸爸是高富帅......");

        // 结尾
        System.out.println("我的爸爸太好了!");
    }
}

class Student_M {
    public void write(){
        // 开头
        System.out.println("\t\t\t\t《我的爸爸》");
        System.out.println("我的爸爸是高富帅......");

        // 结尾
        System.out.println("我的爸爸太好了!");
    }
}

下面,我们定义一个抽象的学生类,把写作正文方法定义在里面,定义成抽象方法,然后把固定的输出开头与结尾的方法定义成普通类(注意,为了体现我们的专业性,要加上final修饰符),在中学生和小学生这两个类里面只需要重写正文的抽象方法即可。

public class Test {
    public static void main(String[] args) {
        Student_M m = new Student_M();
        m.write();
        Student_C c = new Student_C();
        c.write();
    }
}
public abstract class Student {
    public final void write(){
        // 开头
        System.out.println("\t\t\t\t《我的爸爸》");
        System.out.println("我的爸爸是高富帅......");
        // 正文
        System.out.println(writeMain());
        // 结尾
        System.out.println("我的爸爸太好了!");
    }

    public abstract String writeMain();

}
public class Student_M extends Student {
    public String writeMain() {
        return "我的爸爸帅了,是个大明星......";
    }
}

public class Student_C extends Student {
    public String writeMain() {
        return "我的爸爸太有钱了,天天下馆子......";
    }
}

 输出结果:

                《我的爸爸》
我的爸爸是高富帅......
我的爸爸帅了,是个大明星......
我的爸爸太好了!
                《我的爸爸》
我的爸爸是高富帅......
我的爸爸太有钱了,天天下馆子......
我的爸爸太好了!


学与思

与final关键字的联系?

答:为互斥关系

解:abstract定义的抽象类作为模板让子类继承,而final定义的类不能被继承。抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值