目录描述
- 1.super关键字
- 1.1 super概念
- 1.2 代码实例一
- 1.3 代码实例二
- 1.4 代码实例三
- 1.5 代码实例四
- 1.6 代码实例五
- 1.7 代码实例六
- 1.8 代码实例七
- 2.IDEA工具
- 2.1 IDEA工具的使用
- 2.2 IDEA字体设置
- 2.3 IDEA快捷键
- 3.抽象类
- 3.1 抽象类概念
- 3.2 代码实训
- 3.3 抽象方法概念
- 4.接口
- 4.1 接口的基础语法
- 4.2 类和接口之间的实现注意
- 4.3 接口和多态联合使用
- 4.4 一个类实现多个接口
- 4.5 继承和实现都存在的情况
- 4.6 接口在开发中的作用
- 4.7 is a、has a、like a
- 5.抽象类和接口有什么区别
1.super关键字
1.1 super概念
- super是一个关键字,全部小写
- super和this对比着学习
this:
①this能出现在实例方法和构造方法中
②this的语法是:“this.”、“this()”
③this不能使用在静态方法中
④this.大部分情况下是可以省略的
⑤this.什么时候不能省略呢?
答:在区分局部变量和实例变量的时候不能省略,如:
public void setName(String name){ this.name = name; }
⑥this()只能出现在构造方法第一行,通过当前的构造方法去调用"本类"中的其它的构造方法,目的是:代码复用
super:
①super能出现在实例方法和构造方法中
②super的语法是:“super.”、“super()”
③super不能使用在静态方法中
④super.大部分情况下是可以省略的
⑤super.什么时候不能省略呢?
答:父类和子类中有同名属性,或者说有同样的方法。想在子类中访问父类的,super.不能省略。
⑥super()只能出现在构造方法第一行,通过当前的构造方法去调用"父类"中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。 - super()
表示通过子类的构造方法调用父类的构造方法,模拟现实世界中的这种场景:要想有儿子,需要先有父亲 - 重要结论:当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();表示通过当前子类的构造方法调用父类的无参数构造方法,所以必须保证父类的无参数构造方法是存在的 - 注意:this()和super()不能共存,它们都是只能出现在构造方法第一行
- 无论是怎么折腾,父类的构造方法是一定会执行的
1.2 代码实例一
package Super;
public class SuperTest01 {
public static void main(String[] args) {
//创建子类对象
new B();
}
}
class A extends Object{//自动继承
//建议手动的将一个类的无参数构造方法写出来
public A() {
//super();//这里也是默认有这一行代码
System.out.println("A类的无参数构造方法!");
}
//一个类如果没有手动提供任何构造方法,系统会默认提供一个无参构造方法
//一个类如果手动提供了一个构造方法,那么无参数构造系统将不再提供
public A(int i) {
//super();
System.out.println("A类的有参数构造方法(int)!");
}
}
class B extends A{
public B() {
this("zhangsan");
//调用父类中有参数的构造方法
//super(123);
System.out.println("B类的无参数构造方法!");
}
public B(String name) {
super();
System.out.println("B类的有参数构造方法!(String)");
}
}
运行结果:
1.3 代码实例二
- 在java语言中不管是new什么对象,最后老祖宗的Object类的无参数构造方法一定会执行
- Object类的无参数构造方法是处于"栈顶部"
- 栈顶的特定:最后调用,但是最先执行结束;后进先出原则
- 以后写代码的时候,一个类的无参数构造方法还是建议大家手动的写出来。如果无参数构造方法丢失的话,可能会影响到“子类对象的构建”。
package Super;
public class SuperTest02 {
public static void main(String[] args) {
new C();
}
}
class A extends Object{
public A() {
super();
System.out.println("1");
}
}
class B extends A {
public B() {
System.out.println("2");
}
public B(String name) {
System.out.println("3");
}
}
class C extends B {
public C() {//这个是最先调用,但是最后结束
this("zhangsan");
System.out.println("4");
}
public C(String name) {
this(name, 20);
System.out.println("5");
}
public C(String name, int age) {
super(name);
System.out.println("6");
}
}
运行结果:
1.4 代码实例三
- 在恰当的时间使用:super(实际参数列表);
- 注意:在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只创建了一个
- super(实参)的作用:初始化当前对象的父类型特征,并不是创建新对象,实际上对象只创建了1个
- super关键字代表的是“当前对象”的那部分父类型特征
例如:我基础了我父亲的一部分特征,如眼睛和皮肤
super代表的就是眼睛和皮肤,“眼睛和皮肤”虽然是继承了父亲的,但这部分是在我身上的
账户类:
package Super;
public class Account {
//属性
private String actno;
private double balance;
//构造方法
public Account() {
//super();//不写默认会有的
//this.actno = null //默认会有的
//this.balance = 0.0 //默认会有的
}
public Account(String actno, double balance) {
this.actno = actno;
this.balance = balance;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
信用账户:
package Super;
public class CreditAccount extends Account {
//属性:信誉度/诚信度
//子类特有的一个特征,父类没有
private double credit;
//无参的构造方法
public CreditAccount() {
super();//不写默认会有的
//this.credit = 0.0 //默认会有的
}
//带参的构造方法
public CreditAccount(String actno,double balance,double credit) {
//私有属性,只能在本类中访问
//this.actno = actno;
//this.balance = balance;
//以上两行代码在恰当的位置,正好可以使用:super(actno,balance);
//通过子类的构造方法调用父类的构造方法
super(actno,balance);
this.credit = credit;
}
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
}
测试类:
package Super;
public class SuperTest03 {
public static void main(String[] args) {
CreditAccount ca1 = new CreditAccount();
System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit());//输出为:null,0.0,0.0
CreditAccount ca2 = new CreditAccount("111",1000.0,0.999);
System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit());//输出为:111,1000.0,0.999
}
}
内存分析图:
1.5 代码实例四
顾客类:
package Super;
public class Customer {
String name;
public Customer() {
}
public Customer(String name) {
this.name = name;
}
}
贵宾类:
package Super;
public class Vip extends Customer {
public Vip() {
}
public Vip(String name) {
super(name);
}
//super和this都不能出现在静态方法中
public void shopping() {
//this表示当前对象
System.out.println(this.name + "正在购物!");
//super表示的是当前对象的父类型特征。(super是this指向的那个对象中的一块空间)
System.out.println(super.name + "正在购物!");
System.out.println(name + "正在购物!");//此处的name等价于this.name,只是this.可以省略
}
}
测试类:
package Super;
public class SuperTest04 {
public static void main(String[] args) {
Vip v = new Vip("张三");
v.shopping();
}
}
运行结果:
内存分析图:
1.6 代码实例五
- java中允许在子类中出现和父类一样的同名变量/同名属性
- “this.”和“super.”大部分情况下都是可以省略的
- this.什么时候不能省略?
public void setName(String name){
this.name = name;
}
- super.什么时候不能省略?
父中有,子中又有,如果想在子中访问“父的特征”,super.不能省略 - java是怎么来区分子类和父类的同名属性的?
this.name :当前对象的name属性
super.name:当前对象的父类型特征中的name属性
顾客类:
package Super;
public class Customer {
String name;
public Customer() {
}
public Customer(String name) {
super();
this.name = name;
}
public void doSome() {
System.out.println(this.name + "do some!");
System.out.println(name + "do some!");
//错误:找不到符号,父类中没有name属性
//System.out.println(super.name + "do some!");
}
}
贵宾类:
package Super;
public class Vip extends Customer {
//假设子类也有一个同名属性
String name;//实例变量
public Vip() {
}
public Vip(String name) {
super(name);
this.name = null; //不写,默认也会有的
}
//super和this都不能出现在静态方法中
public void shopping() {
//this表示当前对象
System.out.println(this.name + "正在购物!");
//super表示的是当前对象的父类型特征。(super是this指向的那个对象中的一块空间)
System.out.println(super.name + "正在购物!");
System.out.println(name + "正在购物!");//此处的name等价于this.name,只是this.可以省略
}
}
测试类:
package Super;
public class SuperTest05 {
public static void main(String[] args) {
Vip v = new Vip("张三");
v.shopping();
}
}
运行结果:
内存分析图:
1.7 代码实例六
- super不是引用,也不保存内存地址,也不指向任何对象
- super只是代表当前对象内部的那一块父类型的特征
- this和super不能使用在static静态方法中,只能用在实例方法中
package Super;
public class SuperTest06 {
//实例方法
public void doSome() {
//输出“引用”的时候,会自动调用引用的toString()方法
//下面中的this和this.toString()是一样的!!!
System.out.println(this);//输出为:Super.SuperTest06@7de26db8
System.out.println(this.toString());//输出为:Super.SuperTest06@7de26db8
//编译错误:需要'.'
//System.out.println(super);
}
//this和super不能使用在static静态方法中,只能用在实例方法中
/*
* public static void doOther() {
*
* System.out.println(this);
* System.out.println(super.xxx);
*
* }
*/
//静态方法,主方法
public static void main(String[] args) {
SuperTest06 st = new SuperTest06();
st.doSome();
}
}
1.8 代码实例七
- 在父和子中有同名的属性,或者说有相同的方法,如果此时想在子类中访问父中的数据,必须使用“super.”加以区分
- super.属性名【访问父类的属性】
- super.方法名(实参)【访问父类的方法】
- super(实参)【访问父类的构造方法】
动物类:
package Super;
public class Animal {
public void move() {
System.out.println("Animal move!");
}
}
猫类:
package Super;
public class Cat extends Animal {
//对move进行重写
public void move() {
System.out.println("Cat move!");
}
//单独编写一个子类特有的方法
public void yidong() {
this.move();
move();
//super.不仅可以访问属性,也可以访问方法
super.move();
}
}
测试类:
package Super;
public class SuperTest07 {
public static void main(String[] args) {
Cat c = new Cat();
c.yidong();
}
}
运行结果:
2.IDEA工具
关于java的集成开发环境:eclipse、IntelliJ IDEA等
目前主流的集成开发环境是:IntelliJ IDEA
注意:IDEA是自动保存,不需要ctrl + s
2.1 IDEA工具的使用
步骤如下:
- 第一次打开的时候,会弹出一个窗口(import idea settings),这个表示导入idea的设置,但我们是第一次使用idea工具,没有设置过idea,所以选择 :do not import setting…不导入设置
- 接受条款
- don’t send
- 一直下一步(最终选择免费试用30天)
- 可能会让你填写email等信息,这里不填写,继续continue
- 弹出welcome窗口
点击create new project
注意:在IDEA当中一个project相当于eclipse当中的一个workspace - 新建一个Empty Proiect
新建一个空的工程,选择创建工程窗口下面“最后的那一项”,Empty Proiect - 给空的工程起一个名字:javase
存储到:C:\Users…
点击finish - 自动弹出一个每日提示,这个每日提示可以取消掉,以后每一次打开就不再提示
- 会自动弹出一个:project structure,这个窗口先取消掉
- 在空的工程下新建Module(模块),IDEA中模块类似于eclipse当中的project
eclipse的组织方式:workspace—>project
idea的组织方式:project—>module
疑问:怎么创建module?
答:file菜单—>new—>Module - 在New Module窗口上点击左上角的java,然后next
- 给module起一个名字:chapter
- 编写代码,在src目录下新建类,写代码,并运行
2.2 IDEA字体设置
file—>settings—>输入font—>设置字体样式以及字号大小
2.3 IDEA快捷键
快捷键 | 备注 |
psvm | 快速生成main方法 |
sout | 快速生成System.out.println() |
ctrl + y | 删除一行 |
上下箭头 | 左侧窗口中的列表展开和关闭 |
esc | 退出任何窗口 |
alt + insert | 任何新增/新建/添加 |
ctrl + shift + F12 | 窗口变大变小 |
alt + 右箭头/左箭头 | 切换java程序 |
ctrl + shift + F10 | 快速运行程序 |
alt + 标号(1,2,3,…) | 切换窗口 |
ctrl + P | 提示方法的参数 |
Home | 光标回到头 |
End | 光标回到尾 |
ctrl + / | 单行注释 |
ctrl + shift + / | 多行注释 |
按住ctrl + 点击单词 | 定位方法/属性/变量 |
ctrl + d | 复制一行 |
alt + 回车 | 纠正错误 |
ctrl + F12 | 查看一个类的属性和方法 |
3.抽象类
3.1 抽象类概念
- 概念:类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类
- 类本身是不存在的,所以抽象类无法创建对象《无法实例化》
- 抽象类和抽象类实际上可能还有共同特征,还可以进一步再抽象
- 抽象类也属于引用数据类型
- 抽象类定义语法:
[修饰符列表] abstract class 类名{
类体;
}
- 抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的
- final和abstract不能联合使用,这两个关键字是对立的
- 抽象类的子类还可以是抽象类,也可以是非抽象类
- 抽象类虽然无法实例化,但是抽象类有构造方法,这个构造方法是供子类使用的
示例代码:
package Abstract;
public class AbstractTest01 {
public static void main(String[] args) {
//错误:Account是抽象的,无法实例化
//Account act = new Account();
}
}
//非法组合
/*
* final abstract class Account{
*
* }
*/
abstract class Account{
}
class CreditAccount extends Account{
public CreditAccount(){
super();
}
}
//子类继承抽象类,子类可以实例化对象
/*
* class CreditAccount extends Account{
*
* }
*/
抽象类与类与对象的关系说明图:
3.2 代码实训
一个非抽象的类继承抽象类必须将抽象类中的抽象方法实现了(这是java语法上强行规定的,必须的,不然编译器就报错了)
注:这里的实现,也可以叫做覆盖或者重写
动物类(抽象类):
public abstract class Animal{
public abstract void move();
}
子类(非抽象):
public class Bird extends Animal{
//把抽象的方法实现了
public void move(){
System.out.println("鸟儿在飞翔!!!");
}
}
子类(抽象):
public abstract class Maotouying extends Animal{
}
注:如果子类是抽象类的,那么这个Animal中继承过来的抽象方法也可以不去重写/覆盖/实现
测试类:
public class AbstractTest02{
public static void main(String[] args){
//使用多态,父类型指向子类型对象
Animal a = new Bird();//面向抽象编程
a.move();//编译的时候move()方法是Animal的,运行的时候move()方法是Bird的
}
}
3.3 抽象方法概念
抽象类关联到一个概念:抽象方法
概念:没有实现的方法,没有方法体的方法,如:
public abstract void doSome();
抽象类特点:
- 没有方法体,以分号结尾
- 前面修饰符列表中有abstract关键字
注意:
- 抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中
- Java语言中凡是没有方法体的方法都是抽象方法【错】
原因:Object类中就有很多方法都没有方法体,都是以“;”结尾的,但是都不是抽象方法
如:public native int hashCode();
这个方法底层调用了C++写的动态链接程序,前面修饰符列表中没有:abstract。有一个native,表示调用JVM本地程序。
4.接口
4.1 接口的基础语法
- 接口也是一种引用数据类型,编译之后也是一个class字节码文件
- 接口是完全抽象的
- 接口定义语法
[修饰符列表] interface 接口名{}
- 接口支持多继承,一个接口可以继承多个接口
- 接口中只包含两部分内容:常量 + 抽象方法
- 接口中所有的元素都是public修饰的(都是公开的)
- 接口中的抽象方法定义时:public abstract 修饰符可以省略
- 接口中的常量的public static final可以省略
- 接口中的方法都是抽象方法,所以接口中的方法不能有方法体
- 一个非抽象的类,实现接口的时候,必须将接口中所有方法加以实现
- 一个类可以实现多个接口
- extends和implements可以共存,extends在前,implement在后
- 使用接口,写代码的时候,可以使用多态(父类型引用指向子类型对象)
代码示例:
package Test;
public class Test01 {
public static void main(String[] args) {
//访问接口的常量
System.out.println(MyMath.PI);//输出为:3.1415926
//错误:无法为最终变量PI分配值
//MyMath.PI = 3.1415928;
}
}
interface A{
}
interface B extends A{
}
interface C extends A, B{
}
//我的数学接口
interface MyMath{
//定义常量
public static final double PI = 3.1415926;
//public static final可以省略
double PI_a = 3.1415926;
//抽象方法
public abstract int sum1(int a, int b);
//接口当中既然都是抽象方法,那么在编写代码的时候,public abstract可以省略
int sum2(int a, int b);
//错误:接口抽象方法不能带有主体
/*
* void doSome() {
*
* }
*/
}
4.2 类和接口之间的实现注意
- 类和类之间叫做继承,类和接口之间叫做实现
仍可以将“实现”看做“继承”
继承使用extends关键字完成
实现使用implements关键字完成 - 当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖、重写)
package Test;
interface MyMath_wo{
double PI = 3.1415926;
int sum(int a, int b );
int sub(int a, int b );
}
//编写一个类(这个类是一个“非抽象”的类)
class MyMathImpl implements MyMath_wo{
//错误:正在尝试分配更低的访问权限,以前为public
/*
* int sum1(int a, int b )
* { return a + b; }
*/
//重写/覆盖/实现 接口中的方法(通常叫做实现)
public int sum(int a, int b ) {
return a + b;
}
public int sub(int a, int b ) {
return a - b;
}
}
4.3 接口和多态联合使用
package Test;
public class Test02{
public static void main(String[] args) {
//错误:MyMath_wo是抽象的;无法实例化
//new MyMath_wo();
//父类型的引用指向子类型的对象
MyMath_wo mm = new MyMathImpl();
//调用接口里面的方法(面向接口编程)
int result1 = mm.sum(10, 20);
System.out.println(result1);//输出为:30
int result2 = mm.sub(20, 10);
System.out.println(result2);//输出为:10
}
}
interface MyMath_wo{
double PI = 3.1415926;
int sum(int a, int b );
int sub(int a, int b );
}
//编写一个类(这个类是一个“非抽象”的类)
class MyMathImpl implements MyMath_wo{
//错误:正在尝试分配更低的访问权限,以前为public
/*
* int sum1(int a, int b )
* { return a + b; }
*/
//重写/覆盖/实现 接口中的方法(通常叫做实现)
public int sum(int a, int b ) {
return a + b;
}
public int sub(int a, int b ) {
return a - b;
}
}
4.4 一个类实现多个接口
- 一个类可以同时实现多个接口,这种机制弥补了Java中单继承带来的缺陷(Java中类和类只支持单继承,单继承是为了简单而出现的)
- 接口A和接口B虽然没有继承关系,但是写代码的时候,可以互转【编译器不报错,但是运行的时候可能出现:ClassCastException】
- 无论是向上转型还是向下转型,两种类型之间必须要有继承关系,没用继承关系编译器会报错【但这句话不适用在接口方面】
- 接口进行互转的时候还是需要加:instanceof运算符进行判断
代码示例一:
package Test;
public class Test03 {
public static void main(String[] args) {
//多态的使用,父类型引用指向子类型对象
A a = new D();
B b = new D();
C c = new D();
//编译报错:A接口中没用m2()方法
//a.m2();
//这个编译没问题,运行也没问题
B b2 = (B)a;
b2.m2();//输出为:lalalalala
//直接向下转型,这个编译没问题,运行也没问题
D d = (D)a;
d.m2();//输出为:lalalalala
}
}
interface A{
void m1();
}
interface B{
void m2();
}
interface C{
void m3();
}
//实现多个接口,类似于多继承
class D implements A,B,C{
//实现A接口的m1()
public void m1() {
}
//实现B接口的m2()
public void m2() {
System.out.println("lalalalala");
}
//实现C接口的m3()
public void m3() {
}
}
代码示例二:
接口和接口之间在进行强制类型转换的时候,没有继承关系,也可以强转,但是运行的时候可能会出现ClassCastException错误,所以还是用instanceof运算符进行判断。
package Test;
public class Test03 {
public static void main(String[] args) {
M m = new E();
if (m instanceof K) {
K k = (K)m;
}else {
System.out.println("太遗憾了!");
}
}
}
interface K{
}
interface M{
}
class E implements M{
}
运行结果:
总结:接口之间没有继承关系也可以强转,但是在实际操作中没有必要,同时也不要这样做!!!
4.5 继承和实现都存在的情况
语法结果:
class A extends B implements C{
}
代码示例:
package Test;
public class Test04 {
public static void main(String[] args) {
//调用同一个fly()方法,最后的执行效果不同
//多态,创建对象(表面看Animal类没起作用!)
Flyable f = new Cat();
f.fly();//输出为:小猫起飞!!!
//同一个接口
Flyable f1 = new Pig();
f1.fly();//输出为:小猪起飞!!!
//同一个接口
Flyable f2 = new Fish();
f2.fly();//输出为:小鱼起飞!!!
}
}
//动物类:父类
class Animal{
}
//接口:飞翔
//接口通常提取的是行为动作
interface Flyable{
void fly();
}
//动物类子类:猫类
class Cat extends Animal implements Flyable{
public void fly() {
System.out.println("小猫起飞!!!");
}
}
//动物类子类:朱类
class Pig extends Animal implements Flyable{
public void fly() {
System.out.println("小猪起飞!!!");
}
}
//鱼类
//没写extends,也是有的,默认继承Object
/*
1. class Fish implements Flyable{
2. public void fly() {
3. System.out.println("小鱼起飞!!!"); }
4. }
*/
class Fish extends Object implements Flyable{
public void fly() {
System.out.println("小鱼起飞!!!");
}
}
4.6 接口在开发中的作用
- 接口在开发中的作用,类似于多态在开发中的作用
多态:面向抽象编程,不要面向具体编程, 降低程序的耦合度,提高程序的扩展力 - 面向抽象编程可以改为:面向接口编程
- 接口是一个抽象性的概念,扩展性好
- 面向接口编程,可以降低程序的耦合度,提高程序的扩展力,符合OCP开发原则
- 接口的使用离不开多态(接口+多态才可以达到降低耦合度)
- 任何一个接口都有调用者和实现者,调用者面向接口调用,实现者面向接口编写实现
- 接口可以将调用者和实现者解耦合
菜单接口:
package Interface;
public interface FoodMenu {
//西红柿炒蛋
void shiZiChaoJiDan();
//鱼香肉丝
void yuXiangRouSi();
}
中餐厨师:
package Interface;
public class ChinaCooker implements FoodMenu{
public void shiZiChaoJiDan() {
System.out.println("中餐厨师做的西红柿炒鸡蛋!!!");
}
public void yuXiangRouSi() {
System.out.println("中餐厨师做的鱼香肉丝!!!");
}
}
西餐厨师:
package Interface;
public class AmericCooker implements FoodMenu {
public void shiZiChaoJiDan() {
System.out.println("西餐厨师做的西红柿炒鸡蛋!!!");
}
public void yuXiangRouSi() {
System.out.println("西餐厨师做的鱼香肉丝!!!");
}
}
顾客:
package Interface;
public class Customer {
// 如果一下这么写,就写死了,顾客只能吃中餐或者是西餐了
// ChinaCooker cc;
// AmericCooker ac;
// 顾客手中有一个菜单 Customer has a FoodMenu!
// 注意:使用has a来描述,统一以属性的方式存在:实例变量,属性
// 面向抽象编程,面向接口编程,降低程序的耦合度,提高程序的扩展力
private FoodMenu foodMenu;// 都要养成封装的好习惯
//构造方法
public Customer() {
super();
}
public Customer(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
//setter and getter
public FoodMenu getFoodMenu() {
return foodMenu;
}
public void setFoodMenu(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
//提供一个点菜的方法
public void order(){
//先拿到菜单才能点菜
//调用get方法拿菜单
//FoodMenu fm = this.getFoodMenu();
//也可以不调用get方法,因为在本类中私有的属性是考研访问
foodMenu.shiZiChaoJiDan();
foodMenu.yuXiangRouSi();
}
}
测试类:
package Interface;
public class Test {
public static void main(String[] args) {
//创建厨师对象
FoodMenu cooker1 = new ChinaCooker();
//创建顾客对象
Customer customer = new Customer(cooker1);
//顾客点菜
customer.order();
}
}
运行结果:
4.7 is a、has a、like a
类型 | 举例 | 意义 | 代码 |
is a | Cat is a Animal(猫是一个动物) | 凡是能够满足is a的表示“继承关系” | A extends B |
has a | I has a Pen(我有一支笔) | 凡是能够满足has a关系的表示“关联关系”,关联关系通常以“属性”的形式存在 | A{B b;} |
like a | Cooker like a FoodMenu(厨师像一个菜单一样) | 凡是能够满足like a关系的表示“实现关系”,实现关系通常是:类实现接口 | A implements B |
5.抽象类和接口有什么区别
这里只说在语法上的区别
- 抽象类是半抽象的,接口是完全抽象的
- 抽象类有构造方法,接口中没有构造方法
- 接口和接口之间支持多继承,类和类之间只能单继承
- 一个类可以同时实现多个接口,一个抽象类只能继承一个类(单继承)
- 接口中只允许出现常量和抽象方法
- 接口一般都是对“行为”的抽象
注意:以后接口使用的比抽象类多,一般抽象类使用的还是少