(来源:B站黑马程序员—毕向东视频教程笔记)
当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取,只抽取功能定义,不抽取功能主体。
——抽象 = 看不懂
抽象类的特点:
(1)抽象方法一定定义在抽象类中;
(2)抽象方法和抽象类必须被abstract修饰;
(3)抽象类不可以用new创建对象实例,因为调用抽象方法没意义!
(4)抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法后建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类的意义:
- 【1】java中抽象类更利于代码的维护和重用
——因为抽象类不能实例化对象,必须由子类来对抽象方法进行复写后,通过子类来实例化。这样一来,抽象类就不需要改动,只改动子类即可。 - 【2】当项目中需要新增相似的组件时,只需要实现该抽象类,复写其中定义的属性
——比如:学生类里加一类小学生子类,直接继承学生类,并对自己特有的属性和方法进行描述即可。
特殊:抽象类中可以不定义抽象方法,仅为了不让该类建立对象。
//抽象类
abstract class Student//抽象类仅定义,具体功能交给子类
{
//因为后面的子类的方法跟这个相同,但是功能不同,所以父类方法体取消,加分号结束
//此时这个方法就显得很抽象了,所以用abstract修饰,类也要抽象化
abstract void study(); //抽象方法,需要复写
void sleep() //非抽象方法,不用复写
{
System.out.println("躺着");
}
}
//子类1
class BaseStudent extends Student
{
void study()
{
System.out.println("Base study.");
}
}
//子类2
class AdvStudent extends Student
{
void study()
{
System.out.println("Adv study.");
}
}
class AbstractDemo
{
public static void main(String[] args)
{
//BaseStudent bs = new Student();//Studnet是抽象的,无法实例化!
BaseStudent bs = new BaseStudent();
bs.study();
}
}
需求:用继承的思想设计出经理员工类和技术员工类,要求类中必须提供必要的方法进行属性访问。
abstract class Employee//抽象类员工,父类
{
private String name;
private String id;//工号
private double pay;
//构造函数:主要作用是在new将对象的引用返回之前初始化对象
Employee(String name,String id,double pay)
{
this.name = name;//形参与成员名字重名,用this来区别
this.id = id;
this.pay = pay;
}
//抽象方法
public abstract void work();//具体工作不确定,该方法需要抽象化。抽象类就是没法描述得特别具体,需要让子类来处理
}
class Manager extends Employee//经理(也是员工)有自己特由的奖金bonus属性,子类1
{
private int bonus;
Manager(String name,String id,double pay)//构造方法
{
super(name,id,pay);//指向自己父类对象的一个指针,用于引用父类的成员
this.bonus = bonus;
}
public void work()
{
System.out.println("经理干活");
}
}
class Pro extends Employee//专业技术员工,子类2,继承
{
Pro(String name,String id,double pay)//构造方法
{
super(name,id,pay);
}
public void work() //复写父类的抽象方法
{
System.out.println("Pro work.");
}
}
public class AbstractDemo
{
public static void main(String[] args)
{
//因为这里定义了构造器,用于实例化对象时传递成员变量
Pro p = new Pro("xuhui","89757",40.0);
//如果不定义构造器,则系统会默认定义一个空的构造器
p.work();
}
}
需求:获取一段程序运行时间,直接封装到类中————模板方法设计模式
模板方法设计模式:在定义功能时,方法的一部分是确定的,另一部分是不确定的,确定的部分在使用不确定的部分,那么这时:
就将不确定的部分通过抽象方法暴露出去,由该类的子类去完成——提高了复用性和扩展性
abstract class GetTime
{
public final void getTime()//加final,不允许子类改动该方法
{
long begin = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
long res = end-begin;
System.out.println("耗时:"+res+"ms");
}
public abstract void runcode();//抽象方法
}
class subTime extends GetTime//子类
{
public void runcode()//子类对父类抽象方法的复写
{
for(int i=0;i<=1000;i++)
{
System.out.print(i);
}
}
}
public class TemolateDemo
{
public static void main(String[] args)
{
subTime gt = new subTime();
gt.getTime();
}
}