<一>抽象类
一、抽象类含义的概括:
当多个类出现相同功能时,但功能主体不同,这样可以向上抽取,抽取时只抽取功能定义,而不抽取功能主体。也就是说,我们在从下往上看继承这个体系结构时,位于上层的类要比下层更具有通用性,也就是说更加抽象,即最上层的祖先(即超类)最具通用性。这时只讲上层的类作为遗传(或者说派生)下层类的基本的类,而不考虑特定的实例对象。
二、抽象类的特点:
1、抽象方法一定在抽象类中,就是说,一个类中含有抽象方法,这个类也必须是抽象的。
2、抽象方法和抽象类必须被abstract修饰,这是作为抽象(类或方法)的一个标志。
3、抽象类不可用new创建对象,因为调用抽象方法没有意义(抽象方法为类中的成员)。
4、抽象类中的方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用,也就是说,如果子类中只覆盖了部分抽象方法,那么这个子类仍为抽象的,是个抽象类。
总结来说,抽象类,是提供功能的,具体实现形式还是需要由子类来实现的,这就强迫了子类复写抽象类中的抽象方法。需要注意的是,抽象类中是可以有非抽象方法(子类可不必对其复写)的。
备注:
抽象类可以含有普通方法
抽象类不能创建实例对象(不能new)
需要子类覆盖掉所有的抽象方法后才可以创建子类对象,否则子类也必须作为抽象类
列举常见的几个抽象类:
流的四个基本父类
InputStream,OutputStream,Reader,Writer
Ex.
/*
需求:公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
对给出需求进行数据建模。
程序员:
属性:姓名,工号,薪水。
行为:工作内容。
项目经理:
属性:姓名,工号,薪水,奖金。
行为:工作内容。
两者不存在继承,但存在共性,所以向上抽取。
父类是:员工。
员工:抽象
属性:姓名,工号,薪水。
行为:工作。不具体。
*/
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 Programmer extends Employee
{
Programmer(String name,String id,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("code...");
}
}
//描述经理。
class Manager extends Employee
{
private double bonus;
Manager(String name,String id,double pay,double bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{
System.out.println("manage...");
}
}
class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}
}
class Student extends Person
{
Student(String name,int age)
{
super(name,age);
}
void study(){}
}
class Worker extends Person
{
Worker(String name,int age)
{
super(name,age);
}
void work(){}
}
我的总结:
抽象类是类的一种特殊情况:据有类的一切特点,但是不能实例化;一般的都得带有抽象方法。
抽象类不可以实例化,有时看到的近似实例化是多态机制的体现,并不是真正的实例化。
<二> 接口
接口:是一种实现关系
一、接口:
接口可理解为一种特殊的抽象类(但不是),当抽象类中的方法全为抽象的(即不包含任何非抽象方法),可通过接口表示。---- class用来定义类;而interface定义接口
二、定义接口的格式特点:
接口:interface 实现:implements
1、接口中常见定义:常量、抽象方法
2、接口中成员的固定修饰符:
常量:public static final
方法:public abstract
注意:
A、接口中的成员全为public,当然那些修饰符是可以省略的,因为接口会自动设为相应的权限,但是还是最好加上。
B、当接口中的常量赋值后,不可再进行第二次赋值操作。
C、接口不可创建对象,因为其中全为抽象方法,需要被子类实现后,对接口中抽象方法全覆盖后,子类才可以实现实例化。
/*
接口可以简单的理解为是一个特殊的抽象类。
abstract class AbsDemo
{
abstract void show1();
abstract void show2();
}
class Demo extends AbsDemo
{
void show1(){}
void show2(){}
}
*/
//用关键字interface来定义接口。而且内中的成员就固定为几种,而且修饰符是固定的。
//接口中的成员都是public修饰的。
/*
特点:
1,接口不可以实例化。
2,接口的子类必须覆盖接口中所有的抽象方法后,该子类才可以实例化。
否则该子类是抽象类。
*/
interface Inter
{
/*
最常见的成员;全局常量,抽象方法。
*/
public static final int num = 4;
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);
}
}
三、接口可被类多实现,即将java中的多继承改良成多实现。
1、多继承不可以:
是因为父类中的方法有方法体,若多个父类存在相同方法(而方法体不同),子类如果多继承这些父类的话,那么在运行子类的时候,并不能判断出要运行这些父类中的哪个方法,因此程序会出现异常。所以多继承不可以。
2、多实现可以:
是因为接口中的方法是抽象的,并无方法体,无论这些接口中存在多少个同名的方法,由于无方法体,子类只需要覆盖一次即可,这个方法的具体实现只是通过子类这一个方法实现的。
3、接口之间是可以多继承的:
因为接口中存在的是抽象的方法,接口与接口之间无论是否存在同名函数,这些都是需要子类覆盖的,这样就不会出现无法判断覆盖哪一个的问题了。
四、接口的特点:
1、接口是对外暴露的规则
2、接口可以用来多实现
3、接口是程序的扩展功能
4、接口与接口之间可有继承关系
5、接口降低了耦合性
6、类与接口之间是实现关系,且类可以继承一个类的同时实现多个接口
接口关系:like-a; 类关系:has-a
Ex./*
单继承。
class Fu1
{
void show(){}
}
class Fu2
{
void show(){}
}
class Zi extends Fu1,Fu2//不允许。
{
}
*/
interface DemoA
{
void show();
}
interface DemoB
{
void show();
}
class FuDemo
{
void method(){}
}
//最大好处:可以被多实现!一个类可以同时实现多个接口。
/*
class Demo implements DemoA,DemoB
{
public void show(){}
}
*/
//接口的出现避免了单继承的局限性。
class ZiDemo extends FuDemo implements DemoA
{
public void show(){}
}
class InterfaceDemo2
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
interface DemoA
{
void show1();
}
interface DemoAA
{
void show11();
}
interface DemoB extends DemoA,DemoAA//接口上可以有多继承。
{
void show2();
}
class Demo implements DemoB
{
public void show1(){}
public void show2(){}
public void show11(){}
}
class InterfaceDemo3
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
<三> 抽象类和接口的异同
一、概述:
1、抽象类(abstract class):------->一般仅用于被子类继承。
当多个类出现相同功能时,但功能主体不同,这样可以向上抽取,抽取时只抽取功能定义,而不抽取功能主体。也就是说,我们在从下往上看继承这个体系结构时,位于上层的类要比下层更具有通用性,也就是说更加抽象,即最上层的祖先(即超类)最具通用性。这时只讲上层的类作为遗传(或者说派生)下层类的基本的类,而不考虑特定的实例对象。
2、接口(interface):------->用来建立类与类之间关联的标准
接口可理解为一种特殊的抽象类(但不是),当抽象类中的方法全为抽象的
(即不包含任何非抽象方法),可通过接口表示。
简单代码示例:
interface Inter
{
void show1();
void show2();
void show3();
void show4();
}
/*
class InterImpl_1 implements Inter
{
public void show1()
{
System.out.println("show1 run");
}
public void show2(){}
public void show3(){}
public void show4(){}
}
class InterImpl_3 implements Inter
{
public void show3()
{
System.out.println("show3 run");
}
public void show1(){}
public void show2(){}
public void show4(){}
}
*/
//没有抽象方法的抽象类。
abstract class InterImpl implements Inter
{
public void show1(){}
public void show2(){}
public void show3(){}
public void show4(){}
}
class InterImpl_1 extends InterImpl
{
public void show1()
{
System.out.println("show1 run");
}
}
class InterImpl_3 extends InterImpl
{
public void show3()
{
System.out.println("show3 run");
}
}
class InterfaceDemo4
{
public static void main(String[] args)
{
InterImpl_1 in = new InterImpl_1();
in.show1();
}
}
二、区别和联系
一)区别:
1、与类间关系不同:
抽象类是一种被子类继承(extends)的关系,
而接口和类是一种实现(implements)关系,
接口和接口是继承(extends)关系。
注:
a.子类只能继承一个抽象类。
b.一个类却可以实现多个接口。
c.接口可以继承多个接口。
2、定义特点不同:
a.抽象类可以定义变量、非抽象方法以及抽象方法(必须有一个抽象方法)
变量:private、public、final、static等等修饰符
抽象方法:abstract(必须有)、public、static等等修饰符
b.接口可以定义常量、抽象方法
常量:public static final(都是存在的,如果没有会默认加上),赋值后,不可再次赋值
方法:public abstract
3、权限不同:
a.抽象类可以有私有变量或方法,子类继承抽象父类必须复写全部的抽象方法
b.接口是公开(public)的,里面不能有私有变量或方法,因为接口是对外暴露的,是提供给外界使用的;
实现接口必须重写接口中的全部抽象方法
4、成员不同:
a.抽象类中可以有自己的成员,也可以由非抽象的成员方法。
b.接口中只能有静态的不能被修改的成员变量(即常量),而且所有成员方法皆为抽象的。
5、变量类型不同:
a.抽象类中的变量默认是friendly型的,即包内的任何类都可以访问它,而包外的任何类
都不能访问它(包括包外继承了此类的子类),其值可以在子类中重新定义,也可重新赋值。
b.接口中定义的变量是默认的public static final,且必须进行初始化即赋初值,并不可改变。
6、设计理念不同:
a.抽象类表示的是:"si-a"的关系
b.接口表示的是:"like-a"的关系
(组合是"has-a"的关系)
二)联系:
1.其实接口是抽象类的延伸,可以将它看做是纯粹的抽象类,就是说接口比抽象类还抽象。
2、抽象类和接口都必须被一个类(子类)复写里面的全部抽象方法。
3、接口和抽象类都不可创建对象,因为其中含有抽象方法,需要被子类实现后,
对接口中抽象方法全覆盖后,子类才可以实现实例化。