13.1.1抽象类的基本概念
抽象类定义规则如下:
(1)抽象类和抽象方法用abstract关键字修饰
(2)抽象类不能实例化,不能用new 关键字去产生新对象
(3)抽象类方法只需声明,不需实现
(4)含有抽象方法的类必须声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化
abstract class Person{
//抽象类中声明构造方法后,子类必须明确调用
public Person(){}
public abstract void talk();
}
class Student extends Person
class Worker extends Person
s.talk();
w.talk();
//抽象类不能使用final 定义
//在外部抽象类上无法使用static声明,但是内部抽象类可以使用static定义
abstract class Book{
public abstract void print();
static abstract class CD{//静态内部抽象类
public abstract void get();
}
}
class JavaCD extends Book.CD//继承抽象类
{
public void get(){
System.out.println("java 学习");
}
}
public class Test{
public static void main(String[] args){
Book.CD cd=new JavaCD();
cd.get();
}
}
//抽象类之中可以没有静态方法,但是即便没有抽象方法的抽象类也不能够直接在
//外部通过关键字new实例化
13.2.1 接口的基本概念
使用接口的规则:
接口必须有子类,子列依靠implements关键字可以同时实现多个接口
接口的子类(如果不是抽象类0则必须覆盖接口之中的全部抽象方法
接口可以利用对象多态性,利用子类实现对象的实例化
接口与一般类一样,本身也具有数据成员于方法,但是数据成员一定要赋初值,且此值不能再改,方法也必须是抽象方法或defalut方法。在接口定义模式中,抽象方法声明的关键字abstract可以省略
同理,接口的数据成员必须赋初值,且不能更改,fianl关键字也可以省略
interface A{
public static String INFO="Hello,World!";//全局常量
public void print();//抽象方法
defualt public void otherprint()//带方法体的默认方法
{
System.out.println("defualt method");
}
}
//带default方法接口的实现
InterfaceAB ab=new InterfaceAB();
ab.print();
ab.otherprint();
System.out.println(InterfaceA.INFO);
//仅有default方法接口的使用
InterfaceAB ab=new InterfaceAB();
ab.otherprint();
//子类继承多个接口的应用
X x=new X();//X 实现了A、B两个接口
A a=x;//为父接口实例化
B b=x;
a.print();
b.get();
一个类实现多个接口时,若接口中有默认方法,不能出现同名默认方法
多继承中,如果一个子类既要实现接口又要继承抽象类,则应该具有先继承后实现的顺序
interface A{
public static final String INFO="hello";
public abstract void print();
}
class X implements A//继承抽象类
{
public void print(){
System.out.println(INFO);
}
}
public class Test{
public static void main(String[] args){
X x=new X();
A a=x;
a.print();
}
}
//继承抽象类实现接口
X x=new X(); //class X extends C implements A,B
A a=x;
B b=x;
C c=x; //为抽象类实例化
a.print();
b.get();
c.fun();
//一个接口可继承多个接口
X x=new X();
A a=x;
B b=x;
C c=x; //class X extends C implements D
D d=x; //inferface D extends A,B
a.print();
b.get();
c.fun();
d.printD();
13.2.3 接口的作用——制定标准
接口是标准,所谓的标准是各方共同遵守的一个规则。只要操作标准统一了,所有的参与者才可以按照统一的规则操作
比如电脑与外设的连接,USB就是一个操作标准
interface USB{//定义USB接口标准
public void work();//得到USB设备表示要进行的工作
}
class Computer{
public void plugin(USB usb){
//按照固定的方式工作
usb.work();
}
}
class Print implements USB{
public void work(){
System.out.println("打印机用USB接口,连接开始工作");
}
}
class Flash implements USB{
//U盘实现了USB接口
public void work(){
System.out.println("U盘使用了USB接口,连接开始工作");
}
}
public class Test{
public static void main(String args[]){//数以这里主函数的参数发生了变化
Computer com=new Computer();
com.plugin(new Print());//电脑上使用打印机工作
com.plugin(new Flash());//电脑上使用U盘工作
}
}
13.2.4 接口的作用——工厂设计模式
在面向对象设计中,通常最常用的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下,new操作符直接生成会带来一些问题。举例来说,许多类型对象的创造需要一系列的步骤。你可能需要计算或取得对象的初始设置;选择生成哪个子对象实例;或在生成你需要的对象之前必须先生成一些辅助功能的对象。在这些情况,新对象的建立就是一个“过程”,不仅是一个操作,像一部大机器的一个齿轮转动
//接口的作用
interface Fruit{//定义水果标准
public void eat();//吃
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
public class Test{
public static void main(String[] args){
Fruit f=new Apple();
f.eat();
}
}
//此例中发现在主类(客户端)之中直接让一个具体的子类和一个接口绑定在一起,那么
如果要修改使用的子类,对于程序而言,就意味着要修改客户端。所以此时程序就出现了
接口和子类耦合问题,为了解决这一问题,使用工厂模式
//工厂模式
interface Fruit{//定义水果标准
public void eat();//吃
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
class Factory1{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}
if("orange".equals(className)){
return new Orange();
}
return null;
}
}
public class Test{
public static void main(String args[]){
Fruit f=Factory1.getInstance("apple");//初始化参数
f.eat();
}
}
13.2.5 接口的作用——代理设计模式
代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用。
代理,指的就是一个角色代表另一个角色采取行动,就像生活中,一个红酒厂是会
直接把红酒零售给客户的,通常都是通过代理来完成它们的销售业务的。而客户也不为了喝道红酒去找厂商,只需要找到厂商在当地的代理就行了。
这里产生里四个对象:客户、代理商、红酒厂商、代理商-红酒厂商关系
代理模式的作用:为其他对象(红酒厂商)提供一种代理(代理商)以控制对这个对象(红酒厂商)的访问
abstract class Subject//代理请求
{
abstract public void request();
}
class RealSubject extends Subject //真是角色(红酒厂商)
{
public void request(){
System.out.println("我是红酒厂商,欢饮品尝购买!");
}
}
class ProxySubject extends Subject//代理角色(代理商)
{
private RealSubject realSubject;//以真实角色作为代理角色的属性
public void request(){ //该方法封装了真实对象的request方法
preRequest();
if(realSubject==null){
realSubject=new RealSubject();
}
realSubject.request();//此处执行真实对象的request方法
postRequest();
}
private void preRequest(){
System.out.println("广告宣传,免费品尝!");
//something you want to do before requesting
}
private void postRequest(){
System.out.println("付款购买");
//something you want to do after requesting
}
}
public class Test{
public static void main(String[] args){
Subject sub=new ProxySubject();//子类为接口实例化
sub.request();
}
}
//代理模式的核心组成:一个接口、两个子类,一个子类负责真实的业务操作功能
//另一个子类负责完成与真实业务有关的操作
13.3 抽象类和接口的对比
区别 | 抽象类 | 接口 |
---|---|---|
定义语法 | abstract class 类名称{} | interface 接口名称{} |
组成 | 常量、全局变量、变量、构造方法、普通方法、抽象方法 | 全局变量、抽象方法、默认方法 |
权限 | 可以使用各种权限 | 都是public权限 |
使用 | 一个子类可以通过extends关键字继承一个抽象类 | 子类通过implements关键字实现多个接口 |
关系 | 一个抽象类可以实现多个接口 | 一个接口不能继承抽象类,但可以继承多个接口 |
设计模式 | 模板设计模式 | 工厂设计模式、代理设计模式 |
局限 | 单继承局限 | 没有单继承局限 |