1.抽样类
- 1.如何定义抽象类?
— class关键字前加abstract - 2.抽象类方法无法被实例化,抽象类无法创建对象
- 3.虽然抽象类方法无法被实例化,但是抽象类也有构造方法super(),该构造方法是给子类创建对象用的
- 4.抽象类中可以定义抽象方法。
— 抽象方法的语法:在方法的修饰符列表中添加abstract关键字,并且抽象方法应该以“;”结束,不能带有“{}”
— 例如:public abstract void m1(); - 5.抽象类中不一定有抽象方法,但抽象方法必须出现在抽象类中
- 6.一个非抽象的类继承抽象类,必须将抽象类中的方法覆盖、实现、重写,重写后此时非抽象类不可能出现抽象方法
package javase.jingjie.ChouXiang;
public abstract class ChouXiang {
//无参构造方法
ChouXiang() {
System.out.println("ChouXiang......");
}
//抽象方法
public abstract void m1();
//入口
public static void main(String[] args) {
//ChouXiang a=new ChouXiang();//抽象类无法创建对象
//多态,父类创建子类对象
ChouXiang a=new Zilei();
}
}
class Zilei extends ChouXiang{
public void m1() {//重写的方法不是抽象方法
}
Zilei(){
//super();//此处可省略,默认有无参super()出现在构造的第一行,调用父类中的无参构造方法
System.out.println("Zilei...");
}
}
2. 接口
接口也是一种引用类型,可以等同看作类。
- 1.如何定义接口,语法: 【修饰符】interface 接口名{};
- 2.接口中只能出现:常量、抽象方法、静态方法;
- 3.接口其实是一个特殊的抽象类,特殊在接口是完全抽象的;
- 4.接口中没有构造方法,无法被实例化;
- 5.接口和接口之间可以多继承;
- 6.一个类可以继承多个接口;
- 7.一个非抽象的类实现接口,需要将接口中所有的方法实现、重写、覆盖。
(1) 接口
package javase.jingjie.JieKou;
//接口
public interface jiekou {
//接口出现常量(必须用public static final修饰)
public static final String A="success";
public static final double PI=3.14;
//接口中public static final是可以省略的
byte MAX_VALUE=127;//常量
//抽象方法(接口中所有的抽象方法都是public abstract)
public abstract void m1();
//接口中public abstract是可以省略的
void m2();
}
interface B{ //B接口
void m1(); //B接口中的抽象方法
}
interface C{
void m2();
}
interface D{
void m3();
}
//接口和接口之间可以多继承;
interface E extends B,C,D{
void m4();
}
//implements是一个关键字,实现的意思
//implements和extends的意义相同
//一个类可以继承多个接口;
abstract class MyClass implements B,C{
}
//一个非抽象的类实现接口,需要将接口中所有的方法实现覆盖
class M implements B,C,D{
public void m1() {}
public void m2() {}
public void m3() {}
}
(2)接口:Customer案例
package javase.jingjie.JieKou;
/**
* 接口的作用:
* 1.接口可以使项目分层,所有层都面向接口开发,开发效率变高
* 2.接口使代码和代码之间的耦合度降低
* */
public interface Customer {
void logout();//省略了public abstract,抽象方法
}
package javase.jingjie.JieKou;
/**
* 编写接口实现类,该类的编写完全是面向接口去实现的
*
* */
//接口实现,就是继承接口
public class CustomerImp implements Customer {
//非抽象类实现抽象类时(接口是抽象类),需要方法重写
public void logout() {
System.out.println("成功退出系统");
}
}
package javase.jingjie.JieKou;
//程序入口
public class CustomerTest {
public static void main(String[] args) {
// 要执行CustomerImp中的logout方法,以下程序面向接口去调用
Customer cs=new CustomerImp();//多态,父创建子类对象
//引用.
cs.logout();//编译时调用父类Customer,实际运行阶段是子类CustomerImp
}
}
(3)接口:Car案例
1.
— 引擎Engine作接口:
— 发动机YAMAHA、HONDA实现(继承)接口;
— 汽车Car调用接口;
—这样Car通过接口Engine可以更换多种发动机,而引擎接口是不变的
- 2.重要: 接口是中间,实现方继承接口,调用方调用接口,进而调用方通过接口访问实现方
- 3.接口与抽样类的区别:
— 接口与抽样类,优先选择接口(完全抽样类);
— 接口不可以有构造方法存在,接口中抽象方法可以省略public abstract
— 抽象类可以有构造方法存在,抽象类中抽象方法不能省略public abstract
package javase.jingjie.jiekou02;
public interface Engine {
void start();//省略public abstract,抽象方法
}
package javase.jingjie.jiekou02;
//接口实现,Engine是接口
public class HONDA implements Engine {
public void start() {
System.out.println("HONDA启动");
}
}
package javase.jingjie.jiekou02;
//接口实现,Engine是接口
public class YAMAHA implements Engine {
public void start() {
System.out.println("YAMAHA启动");
}
}
package javase.jingjie.jiekou02;
//生产汽车
public class Car {
Engine e;//成员变量e是一个引用,相当于以前的String name,name是一个引用;
//创建构造方法Car,可省略修饰符public,(形参:数据类型 变量)
Car(Engine e) {//括号就是形参
super();//默认调用父类Object构造,可省略
this.e = e;
}
//汽车可以测试引擎
public void testEngine() {
e.start();//面向接口调用,用引用e调用成员方法
}
}
package javase.jingjie.jiekou02;
/**
* 结果:YAMAHA启动
* HONDA启动
* */
//测试类
public class Test {
public static void main(String[] args) {
//1.生产引擎,创建对象
YAMAHA e1=new YAMAHA();
//Engine e1=new YAMAHA();或者用多态,父类创建子类对象
//2.生产汽车,调用有参构造函数
Car c=new Car(e1);
//3.测试引擎
c.testEngine();
//换HONDA,测试引擎
c.e=new HONDA();//这里的e是Engine e,创建new HONDA()对象赋值给e,等于Engine e中存储了HONDA对象
c.testEngine();
}
}