抽象类和抽象类方法、接口、内部类
1、抽象类和抽象方法(abstract关键字)
1、abstract 抽象的
2、abstract可以用来修饰的结构:类、方法
3、abstract 修饰类:抽象类
- 此类不能实例化,抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
- 抽象类中一定有构造器,便于子类实例化的时候调用(涉及:子类对象实例化的过程)
- 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作。
4、abstract修饰方法:抽象方法
- 抽象方法只有方法的声明,没有方法体。
- 包含抽象方法的类一定是抽象类,反之,抽象类中是可以有普通的方法。
- 若子类重写了父类的所有的抽象方法后,此子类方可实例化,若子类没有重写父类的所有抽象方法,此子类也一定是个抽象类,需要使用abstract关键字。(直接父类和间接父类都算)
public class AbstractTest {
public static void main(String[] args) {
// Person p1 = new Person();//抽象类不能实例化
// p1.eat();
}
}
abstract class Creature{
public abstract void breath();//抽象方法,只有方法的声明,没有方法的实现
}
abstract class Person extends Creature{
//继承了Creature但是没有实现父类的抽象方法,Person也为抽象类
String name;
int age;
abstract public void eat();
public void run(){
System.out.println("跑得贼快!");
}
}
class Student extends Person {
//Student继承了Person,Person继承了Creature
@Override
public void eat() {
System.out.println("吃好的!");
}
@Override
public void breath() {
System.out.println("呼吸新鲜空气!");
}
}
abstract 使用上的注意点:
1、abstract 不能用来修饰属性、构造器等结构。
2、abstract不能用来修饰私有方法、静态方法、final的方法、final的类。
思考题:
问题1:为什么抽象类不可以使用final关键字声明?
问题2:一个抽象类中可以定义构造器吗?
问题3:是否可以这样理解:抽象类就是比普通类多定义了抽象方法,除了不能直接进行类的实例化操作之外,并没有任何的不同?
练习:
编写一个Employee类,声明为抽象类,
包含如下三个属性:name,id,salary。
提供必要的构造器和抽象方法:work()。
对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。
请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。
//Manager类
public class Manager extends Employee{
private double bonus;//奖金
public Manager(String name, int id, double salary, double bonus) {
super(name, id, salary);
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("管理员工,提高哦公司运行效率!");
}
}
//CommonEmployee类
public class CommonEmployee extends Employee {
@Override
public void work() {
System.out.println("员工在一线车间生产产品");
}
}
//测试类
public class EmployeeTest {
public static void main(String[] args) {
Employee manager = new Manager("库克",1001,5000,50000);
manager.work();
CommonEmployee commonEmployee = new CommonEmployee();
commonEmployee.work();
}
}
管理员工,提高哦公司运行效率!
员工在一线车间生产产品
抽象匿名子类:自能用一次
作用:图个方便,只能用一次
public class PersonTest {
public static void main(String[] args) {
Worker worker = new Worker();
method1(worker);//非匿名的类非匿名对象
method(new Student());//匿名对象,对象没有名字,对象有(非匿名的类,非匿名的对象)
System.out.println("--------------------");
//*******创建了一个匿名类的对象p,需要做的就是将方法重写*****
Person p = new Person() {
//这个Person是Person的子类,用Person的名字作为充当
@Override
public void eat() {
System.out.println("干饭");
}
@Override
public void breath() {
System.out.println("我感觉不到呼吸");
}
};
method1(p);
System.out.println("----------------");
//*****创建匿名子类的匿名对象*****
method1(new Person() {
@Override
public void eat() {
System.out.println("干饭干饭!!!");
}
@Override
public void breath() {
System.out.println("呼吸都是错的!");
}
});
}
public static void method1(Person p){
p.eat();
p.breath();
}
public static void method(Student p){
}
}
class Worker extends Person{
@Override
public void breath() {
}
@Override
public void eat() {
}
}
干饭
我感觉不到呼吸
干饭干饭!!!
呼吸都是错的!
模板方法的设计模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
例1
/*
抽象类的应用:模板方法的设计模式
*/
public class TemplateTest {
public static void main(String[] args) {
SubTemplate t = new SubTemplate();
t.spendTime();
}
}
//计算某段代码执行所需要花费的时间
abstract class Template{
public void spendTime(){
long start = System.currentTimeMillis();//1970年到现在的毫秒数
code();//不确定的部分(易变的部分)
long end = System.currentTimeMillis();
System.out.println("花费的时间为:"+(end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
@Override
public void code() {
//1000以内的质数
for (int i=2; i<1000;i++){
boolean isFlag = true;
for (int j=2;j<=Math.sqrt(i);j++){
if (i%j==0){
isFlag = false;
break;
}
}
if (isFlag){
System.out.println(i);
}
}
}
}
例2
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
BankTemplateMethod btm2 = new ManageMoney();
btm2.process();
}
}
abstract class BankTemplateMethod {
// 具体方法
public void takeNumber() {
System.out.println("取号排队");
}
public abstract void transact(); // 办理具体的业务 //钩子方法
public void evaluate() {
System.out.println("反馈评分");
}
// 模板方法,把基本操作组合到一起,子类一般不能重写
public final void process() {
this.takeNumber();
this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
this.evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
public void transact() {
System.out.println("我要取款!!!");
}
}
class ManageMoney extends BankTemplateMethod {
public void transact() {
System.out.<