------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
接着昨天的继承下半部分
抽象(abstract)
抽象方法:当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主
体。这样抽取出来方法,只能通过子类复写来实现功能主体,这样的方法称为抽象方法。
而包含这个抽象方法的类就叫做抽象类。
抽象类
抽象类的特点:
1、抽象方法一定在抽象类中。
2、抽象方法和抽象类都必须abstract关键字所修饰
3、抽象类不可以用new创建对象。因为调用抽象方法没意思
4、抽象类中的方法要被使用,必须由子类复写其所有的抽象方法后建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类
看一段代码,看看抽象类的定义格式(抽象类中可以有非抽象方法,也可以有成员变量):
abstract class Student
{
//抽象方法,没有功能主体
abstract void study();
//非抽象方法,子类可以直接调用,或者复写了调用。
void sleep()
{
System.out.println("躺着睡");
}
}
class BaseStudent extends Student
{
//复写抽象类的抽象方法
void study()
{
System.out.println("基础学习");
}
}
//继承抽象类
class AdvStudent extends Student
{
//复写抽象类的抽象方法
void study()
{
System.out.println("高级学习");
}
}
看一个实例,理解抽象类的应用:
/*
假如我们在开发一个系统时需要对员工进行建模,员工包含三个属性:姓名、工号以及工资。
经理也是员工,除了含有员工的属性外,另外还有一个奖金属性。请使用继承的思想设计出员工类
和经理类。要求类中提供必要的方法进行属性访问。
*/
//员工类(父类)
abstract class Employee
{
private String name;
private String id;
private double pay;
//在构造函数中对成员变量初始化
Employee(String name,String id,double pay)
{
this.name=name;
this.id=id;
this.pay=pay;
}
//抽象类(工作内容不确定,需要子类进行复写)
abstract void work();
}
//普通员工类
class Pro extends Employee
{
Pro(String name,String id,double pay)
{
//调用父类的构造函数
super(name,id,pay);
}
//复写父类的抽象方法
void work()
{
System.out.println("普通员工工作内容");
}
}
//经理类,继承员工类
class Manager extends Employee
{
private int bonus;
//在构造函数中对对象的属性初始化
Manager(String name,String id,double pay,int bonus)
{
super(name,id,pay);
this.bonus=bonus;
}
//复写父类的抽象方法
void work()
{
System.out.println("经理工作内容");
}
}
class AbstractTest
{
public static void main(String[] args)
{
System.out.println("抽象类的应用");
}
}
抽象类和一般类的区别
1、抽象类和一般类没有太大的不同。该如何描述事物,就如何描述事物,只不过,该事物中多了一些看不懂的东西。这些不确定的
部分,也是该事物的功能,需要明确出现,但是无法定义主体。
2、抽象类比一般类多了抽象方法。
3、抽象类不可以实例化(即不可以创建对象)
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
模版方法设计模式
什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去。由该类的子类去实现。
看下面代码中对模版方法设计模式的应用
<span style="font-size:14px;">/*
需求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可
获取时间:System.currentTimeMillis();
*/
abstract class GetTime
{
//这个功能是固定的,为避免子类复写这个功能,所以将其用final修饰
public final void getTime()
{
//程度开始时间
long start=System.currentTimeMillis();
//不确定的功能部分
runcode();
//程序结束时间
long end=System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
//因为功能不确定,所以定义为抽象方法,将其暴露出去,以供子类方法重写,实现功能
//当然,这里不是一定得是抽象方法,也可以不是抽象的,只要能让子类复写就可以
public abstract void runcode();
}
class SubTime extends GetTime
{
//复写父类中的抽象方法
public void runcode()
{
for(int x=0;x<4000;x++)
{
System.out.print(x);
}
}
}</span><span style="font-size:18px;">
</span>
接口
接口:初期理解,可以认为是一个特殊的抽象类。当然抽象类中的方法都是抽象的,那么该类可以通过接口的形式来
表示。
class用于定义类,interface用于定义接口
接口定义时,格式特点:
1、接口中常见定义:常量,抽象方法 (接口中的方法都是抽象的)
2、接口中的成员都有固定修饰符
常量:public static final
方法:public abstract
总结:接口中的成员都是public的
接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。否则子类是一个抽象类.
代码:
interface Inter
{
//常量
public static final int NUM=3;
//抽象方法
public abstract void show();
}
class Test implements Inter
{
public void show(){}
}
class InterfaceDemo
{
public static void main(String[] args)
{
Test t=new Test();
System.out.println(t.NUM);
System.out.println(Test.NUM);
System.out.println(Inter.NUM);
//t.NUM=4;//这里编译失败,因为NUM是一个常量,不能赋值
}
}
类与接口之间的多实现implement
接口与接口是继承关系,接口之间可以多层继承,可以多继承
<span style="font-size:14px;">interface Inter
{
//常量
public static final int NUM=3;
//抽象方法
public abstract void show();
}
interface InterA
{
//抽象方法
public abstract void method();
//抽象方法
public abstract void show();
}
class Test implements Inter,InterA
{
//复写接口InterA中的抽象方法method()
public void method(){}
//复写接口InterA和Inter中的抽象方法show()
//这里可以看到类为什么不能多继承,因为多个父类有相同方法的话会引起混乱。
//但多个接口之间有相同方法则不会,因为接口方法中都是抽象方法,没有方法体
public void show(){}
}</span>
接口的特点:
1、接口是对外暴露的规则。
2、接口是程序的功能扩展
3、接口可以用来多实现 (降低了耦合性)
4、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口
5、接口与接口之间可以有继承关系
所以如果实现一个体系中的基本功能时,可以用继承来实现(通过继承来调用或复写体系中的基本功能),如同学生类中有学习的基本功能,不管是小学生还是大学生,所以可以通过继承来实现。而恋爱类,则是属于扩展功能,只有大学生类才能有,而小学生则不能有,则大学生类可以通过接口的方式来实现
看下面的代码:
//抽象学生类
abstract class Student
{
//抽象的学习方法
abstract void study();
//共性内容非抽象的睡觉方法
void sleep()
{
System.out.println("sleep");
}
}
//接口,吸烟
interface Smoking
{
void smoke();
}
//Zhangsan这个对象继承学生类,实现吸烟接口
class Zhangsan extends Student implements Smoking
{
//复写学习方法
void study()
{
System.out.println("Zhangsan_study");
}
//实现接口中的抽象方法,复写吸烟方法
public void smoke()
{
System.out.println("Zhangsan_smoking");
}
}
//Lisi是好学生,不吸烟
class Lisi extends Student
{
//复写学习方法
void study()
{
System.out.println("Lisi_study");
}
}
class InterfaceDemo
{
public static void main(String[] args)
{
//创建两个类的实例对象
Zhangsan z = new Zhangsan();
z.study();
z.smoke();
new Lisi().study();
}
}
结果: