一,抽象类的概述
抽象类定义:
被abstract修饰的类就叫抽象类。
被abstract修饰的方法就叫抽象方法。
eg:
//因为Animal类中出现了抽象类,所以这个类也必须被abstract修饰,这个类就叫抽象类。
abstract class Animal{
String name;
int age;
/*
以下的睡觉方法只是说明动物都具备此行为(行为的定义),具体每种动物如何睡觉
应该在子类中实现,而不应该在父类中实现出来。
因为这个睡觉的方法在动物类具体实现是不符合实际需求,所以没有意义。但是我们还
是需要定义动物有睡觉这个行为。
综合以上的就只有方法定义,没有方法具体实现(就是没有方法体)。
public void sleep(){
System.out.println("动物睡觉");
}
java中规定,没有方法体的方法必须被abstract(抽象)修饰,叫抽象方法。
*/
public abstract void sleep();
}
class Cat extends Animal{
public void sleep(){
System.out.println("猫睡觉");
}
}
public class AbstractDemo{
public static void main(String[] args){
Cat cc=new Cat();
cc . sleep();
}
}
二,抽象类的特点:
1,抽象类必须被abstract修饰。
2,抽象类中是可以没有抽象方法的
3,抽象类中既可以有抽象方法,也可以有普通成员方法。
4,抽象类中是可以有成员变量的,和普通成员变量没有区别。
5,抽象类中是可以有常量的,使用方式和普通类没有区别。
6,抽象中是可以有构造方法的,并且具备构造方法重载特征的。
7,抽象类是不能使用new来创建对象的,就表示在编写程序时是不能直接创建抽象类对象的。
8,抽象类在内存中是有对象存在的,只不过这个对象是JVM通过自己的方式创建的,但是对于
程序是不能直接使用这个对象的。
9,抽象类的使用方法,需要创建其子类,使用抽象类就是使用其某个具体子类的对象。
10,在抽象类的具体子类中,必须实现抽象类中的所有抽象方法。
eg:
abstract class T{
int a=10;
final int b=20;
public T(){}
public T(int a){
this.a=a;
}
public void test(){
a=20;
}
public abstract void test1();
}
class E extends T{
//因为在T类中有抽象方法test1,所以想在E类中直接使用test1方法。
//并且E类是具体类,则必须在E类中实现test1方法。
public void test1(){
System.out.println("在E类中实现了test1方法");
}
}
public class AbstractDemo1{
public static void main(String[] args){
//创建对象
//T tt = new T();抽象类是不能使用new来创建的
//使用抽象类就是使用其某个具体子类的对象
//E ee = new E(); //这样写语法是对的,但是根本没有使用抽象类。
//使用方式是依赖于多态
T t1 = new E();
t1 . test1();
}
}
三,接口的引入
1,定义:
就扣就是定义一套规则,只要你编写的代码符合了这套规则,就叫符合了接口的要求。
2作用:
A,接口代表完成一个抽象该类的规则。
B,打标记。
C,面向接口编程 (重要)
有的时候,在编写程序过程中,为了使用面向接口编程。会硬性的编写接口出来,
这种编码方式就叫做面向接口编程。
四,接口的特点:
1,interface关键字定义接口(不要使用class)。
2,接口中是没有成员变量的,所有的变量都是常量。
实际上全语法是public static final int a=10;
public static final int b=10;
因为所有的常量定义都有public static final ,
所以默认就在定义时不用编写这三个关键字了。
3,接口中是没有构造方法的。
4,接口中所有的方法只有方法定义,没有方法体。都是抽象方法。
public abstract 返回值类型 方法名称(形式参数);
又因为所有的方法都有public abstract关键字,所以以上两个关键字通常不写。
5,接口是没有对象的,接口在内存中只有描述信息,是没有对象的。
6,接口的使用方式,使用接口就是使用实现具体类的对象。
语法:
接口名称 对象引用=new 实现类名称();
在实现类中必须把接口中所有抽象方法都实现,否则这个类就是抽象类。
7,抽象类是可以实现接口的。
8,接口之间是可以多继承的。
9,一个类只能继承一个类,但是可以实现多个接口。
eg:
interface I2{
void test1();
}
interface I3{
void test2();
}
//定义类实现接口I2和I3
class T3 implements I2,I3{
public void test1(){ }
public void test2(){ }
}
//接口可以多继承
interface I extends I2,I3{
int a=10;//默认常量
int b=20;//默认常量
//public I(){} //接口中不能有构造方法
//public void test3(){} //接口中不能有普通方法,只能有方法定义。
void test( );//只能有方法定义,没有方法体。
//因为接口 I 继承了接口I2和I3,所以接口 I 中是有三个抽象方法
}
class T implements I{
public void test(){
System.out.println("实现接口中的Test方法");
}
public void test1(){
System.out.println("实现接口中的Tes1t方法");
}
public void test2(){
System.out.println("实现接口中的Test2方法");
}
}
/*
抽象类是可以实现接口的
abstract class T2 implements I{
因为T2类实现了接口 I ,它就拥有了接口中所有的抽象类方法,
test是抽象的,在T2类中没有具体实现,所以T2类必须是抽象的。
}
*/
public class InterfaceClassDemo{
public static void main(String[] args){
//开始使用接口
// T tt = new T( );只是创建了普通类的对象,根本就没有使用接口
//使用多态
I xx = new T();
xx.test();
}
}
五,具体类,抽象类、接口的区别
1,从是否抽象角度区别
具体的:
具体类
类的三要素
成员变量
成员方法
构造方法
具体类是可以明确对应生活中的某一类事物
使用具体类就是使用其对象。
抽象的:
抽象类
有成员变量
有构造方法
既可以有抽象方法,也可以有具体方法。
抽象类是不能使用new关键字创建对象,但是其在内存中是可以有对象的。
抽象类是可以对应实际生活中某类事物的。
使用抽象类就是使用其某个具体子类的对象(通过多态实现)
接口
只有常量
没有构造方法
所有的方法都是抽象的
接口在内部是不会创建对象的
接口是可以不对应实际生活中的具体事物的。
使用接口就是使用某个具体实现类的对象(通过多态实现)
2,从类 接口角度区别
类和类之间:
类和类之间是有继承关系的
类和类之间只能是单继承
类和类之间是可以有继承体系的
如果是具体类继承抽象类,则在具体类中需要把抽象类的所有抽象方法都实现。
接口和接口之间:
接口和接口之间是继承关系
接口和接口之间是多继承关系
接口和接口之间可以有继承体系
类和接口之间:
类和接口是实现关系
抽象类实现接口,则这个抽象类拥有了接口的所有抽象方法(可实现,可不实现);
具体类实现接口,则这个具体类必须把接口的所有抽象方法都实现出来。
六,面向接口编程
1,定义:
编程中肯定需要使用接口。
2,面向接口编程的分类
普通java程序的类和类之间的面向接口编程。
系统的分层中的层和层之间的面向接口编程。
3,使用接口的好处
使用接口就意味着使用多态,就可以使类符合开放封闭原则。
使用接口就是为了解耦和(类和类之间,层和层之间)
耦合:就是说A和B关系很紧密,其中任何一个发生改变,则就会造成另一个发生改变。
解耦和:就是尽量使A和B关系不紧密,尽量让任意一个发生改变,不会造成另外一个发生改变。
eg:
//老师开车回家
class Teacher{
String name;
int age;
//如果没有接口
//5年之前开捷达车
//public void goHome(JD xx){ }
//5年之后开奔驰车
//public void goHome(BC xx){ }
/*
以上过程就是因为goHome方法总是依赖于具体类,才造成了需求改变,就必须随着需求改动代码。
以下代码就是因为goHome方法依赖接口了,所以需求发生改变,代码不用改变。
以上的处理模式叫做把goHome方法和具体的车类解耦和。
*/
//使用车回家
public void goHome(Car xx){
xx.move();
}
}
/*
现在写的代码已经很好的实现了类的编码模式中的开放封闭原则了,但是因为是抽象类,
它在使用中是会在内存创建对象的,往往在这里习惯用接口。
abstract calss Car{
String name;
double xn;
public abstract void move( );
}
*/
interface Car{
void move ();
}
//因为是接口,所以要实现接口。
class JD implements Car{
public void move(){
System.out.println("捷达车开始启动");
}
}
class BC implements Car{
public void move(){
System.out.println("奔驰车开始启动");
}
}
public class InterfaceClassDome{
public static void main(String[] args){
Teacher tt=new Teacher();
//Car xx=new JD();
//tt.goHomea(xx);
//5年之前开捷达车
tt.goHome(new JD());//使用多态,这是上面多态的匿名对象。
//5年之后开奔驰车
tt.goHome(new BC());//使用多态
}
}