09.01 final关键字引入
例:
1 class Fu 2 { 3 public final void show() 4 { 5 System.out.println("访问底层资源"); 6 } 7 } 8 class Zi extends Fu 9 { 10 public void show() 11 { 12 System.out.println("Zi show run"); 13 } 14 } 15 class Demo 16 { 17 public static void main(String[] args) 18 { 19 Zi z = new Zi(); 20 z.show(); 21 } 22 }
上面的代码中父类中的show()方法如果不想被子类覆盖,可以使用final关键字修饰,当子类覆盖了父类中的show()方法,将会报以下错误:
final关键字是最终的意思,可以修饰类,成员变量,成员方法
09.02 final关键字修饰类,方法以及变量的特点
修饰类,类不能被继承
修饰方法,方法不能被重写
修饰变量,变量就变成了常量,只能被赋值一次
09.03 final关键字修饰局部变量
例:
1 class Student 2 { 3 int age = 10; 4 } 5 class Demo 6 { 7 public static void main(String[] args) 8 { 9 //final修饰基本类型的局部变量 10 final int x = 10; 11 //x = 20; 值不能被改变 12 System.out.println(x); 13 14 //final修饰引用类型的局部变量 15 final Student s = new Student(); 16 //s = new Student(); 引用类型的地址值不能变 17 s.age = 20; 18 System.out.println(s.age); 19 } 20 }
final修饰基本类型的局部变量,该变量的值不能被改变
final修饰引用类型的局部变量,引用类型的地址值不能变
09.04 final修饰变量的初始化时机
例:
1 class Test 2 { 3 int num1; 4 final int num2; //在对象构造完毕前即可 5 public Test() 6 { 7 num1 = 100; 8 num2 = 200; 9 } 10 } 11 class Demo 12 { 13 public static void main(String[] args) 14 { 15 Test t = new Test(); 16 System.out.println(t.num1); 17 System.out.println(t.num2); 18 } 19 }
09.05 多态的概述和前提条件
多态概述:某一个对象,在不同时刻表现出来的不同状态。
举例:猫可以是猫的类型。Cat c = new Cat();
同时猫也是动物的一种,也可以把猫称为动物。Animal a = new Animal();
多态的前提:
1.有继承关系
2.有方法重写
3.有父类引用指向子类对象
09.06 按照多态前提给出代码体现
1 class Fu 2 { 3 public void show() 4 { 5 System.out.println("Fu show run") 6 } 7 } 8 class Zi extends Fu 9 { 10 public void show() 11 { 12 System.out.println("Zi show run") 13 } 14 } 15 class Demo 16 { 17 public static void main(String[] args) 18 { 19 //父类引用指向子类对象 20 Fu f = new Zi(); 21 } 22 }
09.07 多态中的成员访问特点
1.成员变量 编译看左边,运行看左边
例:
1 class Fu 2 { 3 public int num1 = 10; 4 } 5 class Zi extends Fu 6 { 7 public int num1 = 20; 8 public int num2 = 30; 9 10 } 11 class Demo 12 { 13 public static void main(String[] args) 14 { 15 //编译时查看Fu类中是否有num1,有就编译通过 16 Fu f = new Zi(); 17 //运行时输出Fu类中的num1 18 System.out.println(f.num1); 19 //Fu类中没有num2,编译失败 20 //System.out.println(f.num2); 21 } 22 }
2.成员方法 编译看左边,运行看右边
例:
1 class Fu 2 { 3 public void show() 4 { 5 System.out.println("Fu show run"); 6 } 7 8 } 9 class Zi extends Fu 10 { 11 public void show() 12 { 13 System.out.println("Zi show run"); 14 } 15 public void method() 16 { 17 System.out.println("Zi method run"); 18 } 19 20 } 21 class Demo 22 { 23 public static void main(String[] args) 24 { 25 Fu f = new Zi(); 26 //编译时查看Fu类中是否有show()方法,有就编译通过 27 //运行时输出Zi类中show()方法 28 f.show(); 29 //Fu类中没有num2,编译失败 30 //f.method(); 31 } 32 }
3.静态方法 编译看左边,运行看左边(静态方法与类相关,不能算方法的重写)
例:
1 class Fu 2 { 3 public static void show() 4 { 5 System.out.println("Fu show run"); 6 } 7 8 } 9 class Zi extends Fu 10 { 11 public static void show() 12 { 13 System.out.println("Zi show run"); 14 } 15 public void method() 16 { 17 System.out.println("Zi method run"); 18 } 19 20 } 21 class Demo 22 { 23 public static void main(String[] args) 24 { 25 Fu f = new Zi(); 26 //编译时查看Fu类中是否有show()方法,有就编译通过 27 //运行时输出Fu类中show()方法 28 f.show(); 29 } 30 }
09.08 多态的好处
多态的好处
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
例:
1 class Animal 2 { 3 public void eat() 4 { 5 System.out.println("eat"); 6 } 7 } 8 class Cat extends Animal 9 { 10 public void eat() 11 { 12 System.out.println("猫吃鱼"); 13 } 14 } 15 class Dog extends Animal 16 { 17 public void eat() 18 { 19 System.out.println("狗吃肉"); 20 } 21 } 22 class Demo 23 { 24 public static void main(String[] args) 25 { 26 Cat c = new Cat(); 27 Dog d = new Dog(); 28 method(c); 29 method(d); 30 } 31 //提高了代码的扩展性,前期定义的代码可以使用后期的内容 32 public static void method(Animal a) 33 { 34 a.eat(); 35 } 36 }
09.09 多态的弊端
多态的弊端:不能访问子类特有功能
例:
1 class Fu 2 { 3 public void show() 4 { 5 System.out.println("Fu show run"); 6 } 7 } 8 class Zi extends Fu 9 { 10 public void show() 11 { 12 System.out.println("Zi show run"); 13 } 14 public void method() 15 { 16 System.out.println("Zi method run"); 17 } 18 } 19 class Demo 20 { 21 public static void main(String[] args) 22 { 23 Fu f = new Zi(); 24 f.show(); 25 //错误,不能访问子类特有功能 26 //f.method(); 27 } 28 }
09.10 多态中向上转型和向下转型
例:
1 class Fu 2 { 3 public void show() 4 { 5 System.out.println("Fu show run"); 6 } 7 } 8 class Zi extends Fu 9 { 10 public void show() 11 { 12 System.out.println("Zi show run"); 13 } 14 public void method() 15 { 16 System.out.println("Zi method run"); 17 } 18 } 19 class Demo 20 { 21 public static void main(String[] args) 22 { 23 Fu f = new Zi(); 24 f.show(); 25 //使用向下转型以使用子类特有方法 26 Zi z = (Zi)f; 27 z.method(); 28 } 29 }
运行结果:
Zi show run
Zi method run
向上转型:从子到父,父类引用指向子类对象。例:Fu f = new Zi();
向下转型:从父到子,父类引用转为子类对象。例:Zi z = (Zi)f;
09.11 孔子装爹案例讲解多态现象
多态的问题理解:
1 class 孔子爹 2 { 3 public int age = 40; 4 5 public void teach() 6 { 7 System.out.println("讲解JavaSE"); 8 } 9 } 10 11 class 孔子 extends 孔子爹 12 { 13 public int age = 20; 14 public void teach() 15 { 16 System.out.println("讲解论语"); 17 } 18 public void playGame() 19 { 20 System.out.println("英雄联盟"); 21 } 22 } 23 24 //Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了 25 //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢? 26 //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹 27 //向上转型 28 孔子爹 k爹 = new 孔子(); 29 //到人家那里去了 30 System.out.println(k爹.age); //40 31 k爹.teach(); //讲解论语 32 //k爹.playGame(); //这是儿子才能做的 33 34 //讲完了,下班回家了 35 //脱下爹的装备,换上自己的装备 36 //向下转型 37 孔子 k = (孔子) k爹; 38 System.out.println(k.age); //20 39 k.teach(); //讲解论语 40 k.playGame(); //英雄联盟
09.12 多态继承中的内存图解
09.13 多态中的对象变化内存图解
09.14 猫狗案例多态版
1 class Animal 2 { 3 public void eat() 4 { 5 System.out.println("吃饭"); 6 } 7 } 8 class Cat extends Animal 9 { 10 public void eat() 11 { 12 System.out.println("猫吃鱼"); 13 } 14 public void playGame() 15 { 16 System.out.println("猫玩游戏"); 17 } 18 } 19 class Dog extends Animal 20 { 21 public void eat() 22 { 23 System.out.println("狗吃肉"); 24 } 25 public void lookDoor() 26 { 27 System.out.println("狗看门"); 28 } 29 } 30 class Demo 31 { 32 public static void main(String[] args) 33 { 34 Animal a = new Dog(); 35 a.eat(); 36 Dog d = (Dog)a; 37 d.lookDoor(); 38 System.out.println("------"); 39 a = new Cat(); 40 a.eat(); 41 Cat c = (Cat)a; 42 c.playGame(); 43 } 44 }
运行结果:
狗吃肉 狗看门 ------ 猫吃鱼 猫玩游戏
09.15 南北方人案例
1 class Person 2 { 3 String name; 4 Person(String name) 5 { 6 this.name = name; 7 System.out.println(name); 8 } 9 public void eat() 10 { 11 System.out.println("吃饭"); 12 } 13 } 14 15 class SouthPerson extends Person 16 { 17 SouthPerson(String name) 18 { 19 super(name); 20 } 21 public void eat() 22 { 23 System.out.println("炒菜,吃米饭"); 24 } 25 26 public void jingShang() 27 { 28 System.out.println("经商"); 29 } 30 } 31 32 class NorthPerson extends Person 33 { 34 NorthPerson(String name) 35 { 36 super(name); 37 } 38 public void eat() 39 { 40 System.out.println("炖菜,吃馒头"); 41 } 42 43 public void yanJiu() 44 { 45 System.out.println("研究"); 46 } 47 } 48 class Demo 49 { 50 public static void main(String[] args) 51 { 52 //测试 53 //南方人 54 Person p = new SouthPerson("南方人"); 55 p.eat(); 56 SouthPerson sp = (SouthPerson)p; 57 sp.jingShang(); 58 System.out.println("--------"); 59 60 //北方人 61 p = new NorthPerson("北方人"); 62 p.eat(); 63 NorthPerson np = (NorthPerson)p; 64 np.yanJiu(); 65 } 66 }
运行结果:
南方人 炒菜,吃米饭 经商 -------- 北方人 炖菜,吃馒头 研究
09.16 多态的练习题看程序写结果
1.看程序写结果:先判断有没有问题,如果没有,写出结果
1 class Fu 2 { 3 public void show() 4 { 5 System.out.println("fu show run"); 6 } 7 } 8 9 class Zi extends Fu 10 { 11 public void show() 12 { 13 System.out.println("zi show run"); 14 } 15 16 public void method() 17 { 18 System.out.println("zi method run"); 19 } 20 } 21 class Demo 22 { 23 public static void main(String[] args) 24 { 25 Fu f = new Zi(); 26 //找不到符号 27 //f.method(); 28 f.show(); 29 } 30 }
运行结果:
zi show run
2.看程序写结果:先判断有没有问题,如果没有,写出结果
1 class A 2 { 3 public void show() 4 { 5 show2(); 6 } 7 public void show2() 8 { 9 System.out.println("hello "); 10 } 11 } 12 class B extends A 13 { 14 /* 15 //从父类继承 16 public void show() 17 { 18 show2(); 19 } 20 */ 21 22 public void show2() 23 { 24 System.out.println("world "); 25 } 26 } 27 class C extends B 28 { 29 public void show() 30 { 31 super.show(); 32 } 33 public void show2() 34 { 35 System.out.println("java "); 36 } 37 } 38 class Demo 39 { 40 public static void main(String[] args) 41 { 42 A a = new B(); 43 a.show(); 44 45 B b = new C(); 46 b.show(); 47 } 48 }
运行结果:
world
java
09.17 抽象类的引入
动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。同理,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
09.18 抽象类的特点
抽象类特点:
1.抽象类和抽象方法必须用abstract关键字修饰
格式: abstract class 类名 {}
public abstract void method();
2.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
3.抽象类不能实例化,因为抽象类不是具体的,抽象类有构造方法,按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
4.抽象类的子类如果不重写父类中的抽象方法,那么该子类还是抽象类,否则必须重写抽象类中的所有抽象方法
例:
1 abstract class Animal 2 { 3 public abstract void eat(); 4 } 5 class Cat extends Animal 6 { 7 public void eat() 8 { 9 System.out.println("猫吃鱼"); 10 } 11 } 12 class Demo 13 { 14 public static void main(String[] args) 15 { 16 //多态 17 Animal a = new Cat(); 18 a.eat(); 19 } 20 }
运行结果:
猫吃鱼
09.19 抽象类的成员特点
成员变量:可以是变量,也可以是常量
构造方法:有构造方法,但是不能实例化,构造方法的作用是用于子类访问父类数据的初始化
成员方法:可以有抽象方法限定子类必须完成某些动作,也可以有非抽象方法提高代码复用性
例:
1 abstract class Animal 2 { 3 public int num1 = 10;//变量 4 public final int num2 = 20;//常量 5 public Animal(){}//构造函数 6 public abstract void show();//抽象方法 7 public void method()//非抽象方法 8 { 9 System.out.println("Animal method run"); 10 } 11 } 12 class Cat extends Animal 13 { 14 public void show() 15 { 16 System.out.println("Cat show run"); 17 } 18 } 19 class Demo 20 { 21 public static void main(String[] args) 22 { 23 //创建对象 24 Animal a = new Cat(); 25 System.out.println(a.num1);//访问变量 26 System.out.println(a.num2);//访问常量 27 a.show();//访问抽象方法 28 a.method();//访问非抽象方法 29 } 30 }
运行结果:
10
20
Cat show run
Animal method run
09.20 抽象类练习猫狗案例
1 /* 2 猫狗案例 3 具体事物:猫,狗 4 共性:姓名,年龄,吃饭 5 6 分析:从具体到抽象 7 猫: 8 成员变量:姓名,年龄 9 构造方法:无参,带参 10 成员方法:吃饭(猫吃鱼) 11 12 狗: 13 成员变量:姓名,年龄 14 构造方法:无参,带参 15 成员方法:吃饭(狗吃肉) 16 17 因为有共性的内容,所以就提取了一个父类。动物。 18 但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的, 19 而方法是抽象的类,类就必须定义为抽象类。 20 21 抽象动物类: 22 成员变量:姓名,年龄 23 构造方法:无参,带参 24 成员方法:吃饭(); 25 26 实现:从抽象到具体 27 动物类: 28 成员变量:姓名,年龄 29 构造方法:无参,带参 30 成员方法:吃饭(); 31 32 狗类: 33 继承自动物类 34 重写吃饭(); 35 36 猫类: 37 继承自动物类 38 重写吃饭(); 39 */ 40 abstract class Animal 41 { 42 //姓名 43 private String name; 44 //年龄 45 private int age; 46 47 public Animal() {} 48 49 public Animal(String name,int age) 50 { 51 this.name = name; 52 this.age = age; 53 } 54 55 public String getName() 56 { 57 return name; 58 } 59 60 public void setName(String name) 61 { 62 this.name = name; 63 } 64 65 public int getAge() 66 { 67 return age; 68 } 69 70 public void setAge(int age) 71 { 72 this.age = age; 73 } 74 75 //定义一个抽象方法 76 public abstract void eat(); 77 } 78 //定义具体的狗类 79 class Dog extends Animal 80 { 81 public Dog() {} 82 83 public Dog(String name,int age) 84 { 85 super(name,age); 86 } 87 88 public void eat() 89 { 90 System.out.println("狗吃肉"); 91 } 92 } 93 94 //定义具体的猫类 95 class Cat extends Animal 96 { 97 public Cat() {} 98 99 public Cat(String name,int age) 100 { 101 super(name,age); 102 } 103 104 public void eat() 105 { 106 System.out.println("猫吃鱼"); 107 } 108 } 109 class Demo 110 { 111 public static void main(String[] args) 112 { 113 //测试狗类,具体类用法 方式1 114 Dog d = new Dog(); 115 d.setName("旺财"); 116 d.setAge(3); 117 System.out.println(d.getName()+"---"+d.getAge()); 118 d.eat(); 119 //测试狗类,具体类用法 方式2: 120 Dog d2 = new Dog("旺财",3); 121 System.out.println(d2.getName()+"---"+d2.getAge()); 122 d2.eat(); 123 System.out.println("-------------"); 124 //测试狗类,多态用法 方式1: 125 Animal a = new Dog(); 126 a.setName("旺财"); 127 a.setAge(3); 128 System.out.println(a.getName()+"---"+a.getAge()); 129 a.eat(); 130 //测试狗类,多态用法 方式2: 131 Animal a2 = new Dog("旺财",3); 132 System.out.println(a2.getName()+"---"+a2.getAge()); 133 a2.eat(); 134 } 135 }
运行结果:
旺财---3 狗吃肉 旺财---3 狗吃肉 ------------- 旺财---3 狗吃肉 旺财---3 狗吃肉
09.21 抽象类练习老师案例
1 /* 2 老师案例 3 具体事物:基础班老师,就业班老师 4 共性:姓名,年龄,讲课。 5 6 分析: 7 基础班老师 8 姓名,年龄 9 讲课。 10 就业班老师 11 姓名,年龄 12 讲课。 13 实现: 14 老师类 15 基础班老师 16 就业班老师 17 */ 18 //定义抽象的老师类 19 abstract class Teacher 20 { 21 //姓名 22 private String name; 23 //年龄 24 private int age; 25 26 public Teacher() {} 27 28 public Teacher(String name,int age) 29 { 30 this.name = name; 31 this.age = age; 32 } 33 34 public String getName() 35 { 36 return name; 37 } 38 39 public void setName(String name) 40 { 41 this.name = name; 42 } 43 44 public int getAge() 45 { 46 return age; 47 } 48 49 public void setAge(int age) 50 { 51 this.age = age; 52 } 53 54 //抽象方法 55 public abstract void teach(); 56 } 57 58 //基础班老师类 59 class BasicTeacher extends Teacher 60 { 61 public BasicTeacher(){} 62 63 public BasicTeacher(String name,int age) 64 { 65 super(name,age); 66 } 67 68 public void teach() 69 { 70 System.out.println("基础班老师讲解JavaSE"); 71 } 72 } 73 74 //就业班老师类 75 class WorkTeacher extends Teacher 76 { 77 public WorkTeacher(){} 78 79 public WorkTeacher(String name,int age) 80 { 81 super(name,age); 82 } 83 84 public void teach() 85 { 86 System.out.println("就业班老师讲解JavaEE"); 87 } 88 } 89 class Demo 90 { 91 public static void main(String[] args) 92 { 93 //多态测试 94 //基础班老师 95 Teacher t = new BasicTeacher(); 96 t.setName("小明"); 97 t.setAge(30); 98 System.out.println(t.getName()+"---"+t.getAge()); 99 t.teach(); 100 System.out.println("--------------------"); 101 102 t = new BasicTeacher("小明",30); 103 System.out.println(t.getName()+"---"+t.getAge()); 104 t.teach(); 105 System.out.println("--------------------"); 106 107 //就业班老师 108 t = new WorkTeacher(); 109 t.setName("小红"); 110 t.setAge(35); 111 System.out.println(t.getName()+"---"+t.getAge()); 112 t.teach(); 113 System.out.println("--------------------"); 114 115 t = new WorkTeacher("小红",35); 116 System.out.println(t.getName()+"---"+t.getAge()); 117 t.teach(); 118 } 119 }
运行结果:
小明---30 基础班老师讲解JavaSE -------------------- 小明---30 基础班老师讲解JavaSE -------------------- 小红---35 就业班老师讲解JavaEE -------------------- 小红---35 就业班老师讲解JavaEE
09.22 抽象类练习学员案例
1 /* 2 学生案例 3 具体事务:基础班学员,就业班学员 4 共性:姓名,年龄,班级,学习,吃饭 5 6 分析: 7 基础班学员 8 成员变量:姓名,年龄,班级 9 成员方法:学习,吃饭 10 就业班学员 11 成员变量:姓名,年龄,班级 12 成员方法:学习,吃饭 13 14 得到一个学员类。 15 成员变量:姓名,年龄,班级 16 成员方法:学习,吃饭 17 18 实现: 19 学员类 20 基础班学员 21 就业班学员 22 */ 23 //定义抽象学员类 24 abstract class Student 25 { 26 //姓名 27 private String name; 28 //年龄 29 private int age; 30 //班级 31 private String grand; 32 33 public Student() {} 34 35 public Student(String name,int age,String grand) 36 { 37 this.name = name; 38 this.age = age; 39 this.grand = grand; 40 } 41 42 public String getName() 43 { 44 return name; 45 } 46 47 public void setName(String name) 48 { 49 this.name = name; 50 } 51 52 public int getAge() 53 { 54 return age; 55 } 56 57 public void setAge(int age) 58 { 59 this.age = age; 60 } 61 62 public String getGrand() 63 { 64 return grand; 65 } 66 67 public void setGrand(String grand) 68 { 69 this.grand = grand; 70 } 71 72 //学习 73 public abstract void study(); 74 75 //吃饭 76 public void eat() 77 { 78 System.out.println("吃饭"); 79 } 80 } 81 82 //具体基础班学员类 83 class BasicStudent extends Student 84 { 85 public BasicStudent() {} 86 87 public BasicStudent(String name,int age,String grand) 88 { 89 super(name,age,grand); 90 } 91 //重写父类抽象方法 92 public void study() 93 { 94 System.out.println("基础班学员学习JavaSE"); 95 } 96 } 97 98 //具体就业班学员类 99 class WorkStudent extends Student 100 { 101 public WorkStudent() {} 102 103 public WorkStudent(String name,int age,String grand) 104 { 105 super(name,age,grand); 106 } 107 //重写父类抽象方法 108 public void study() 109 { 110 System.out.println("就业班学员学习JavaEE"); 111 } 112 } 113 class Demo 114 { 115 public static void main(String[] args) 116 { 117 //按照多态的方式测试基础班学员 118 Student s = new BasicStudent(); 119 s.setName("小明"); 120 s.setAge(27); 121 s.setGrand("1111"); 122 System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand()); 123 s.study(); 124 s.eat(); 125 System.out.println("--------------"); 126 127 s = new BasicStudent("小红",28,"1111"); 128 System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand()); 129 s.study(); 130 s.eat(); 131 } 132 }
运行结果:
小明---27---1111 基础班学员学习JavaSE 吃饭 -------------- 小红---28---1111 基础班学员学习JavaSE 吃饭
09.23 抽象类练习员工案例
假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
1 /* 2 3 分析: 4 普通员工类 5 成员变量:姓名、工号以及工资。 6 成员方法:工作 7 经理类: 8 成员变量:姓名、工号以及工资,奖金属性 9 成员方法:工作 10 11 实现: 12 员工类: 13 普通员工类: 14 经理类: 15 */ 16 //定义员工类 17 abstract class Employee 18 { 19 //姓名、工号以及工资 20 private String name; 21 private String id; 22 private int salary; 23 24 public Employee() {} 25 26 public Employee(String name,String id,int salary) 27 { 28 this.name = name; 29 this.id = id; 30 this.salary = salary; 31 } 32 33 public String getName() 34 { 35 return name; 36 } 37 38 public void setName(String name) 39 { 40 this.name = name; 41 } 42 43 public String getId() 44 { 45 return id; 46 } 47 48 public void setId(String id) 49 { 50 this.id = id; 51 } 52 53 public int getSalary() 54 { 55 return salary; 56 } 57 58 public void setSalary(int salary) 59 { 60 this.salary = salary; 61 } 62 63 //工作 64 public abstract void work(); 65 } 66 67 //普通员工类 68 class Programmer extends Employee 69 { 70 public Programmer(){} 71 72 public Programmer(String name,String id,int salary) 73 { 74 super(name,id,salary); 75 } 76 77 public void work() 78 { 79 System.out.println("按照需求写代码"); 80 } 81 } 82 83 //经理类 84 class Manager extends Employee 85 { 86 //奖金 87 private int money; 88 89 public Manager(){} 90 91 public Manager(String name,String id,int salary,int money) 92 { 93 super(name,id,salary); 94 this.money = money; 95 } 96 97 public void work() 98 { 99 System.out.println("跟客户谈需求"); 100 } 101 102 public int getMoney() 103 { 104 return money; 105 } 106 107 public void setMoney(int money) 108 { 109 this.money = money; 110 } 111 } 112 class Demo 113 { 114 public static void main(String[] args) 115 { 116 //测试普通员工 117 Employee emp = new Programmer(); 118 emp.setName("小明"); 119 emp.setId("czbk001"); 120 emp.setSalary(18000); 121 System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); 122 emp.work(); 123 System.out.println("-------------"); 124 emp = new Programmer("小明","czbk001",18000); 125 System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary()); 126 emp.work(); 127 System.out.println("-------------"); 128 129 //由于子类有特有的内容,所以我们用子类来测试 130 Manager m = new Manager(); 131 m.setName("小红"); 132 m.setId("czbk002"); 133 m.setSalary(8000); 134 m.setMoney(2000); 135 System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); 136 m.work(); 137 System.out.println("-------------"); 138 139 //通过构造方法赋值 140 m = new Manager("小红","czbk002",8000,2000); 141 System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney()); 142 m.work(); 143 } 144 }
运行结果:
小明---czbk001---18000 按照需求写代码 ------------- 小明---czbk001---18000 按照需求写代码 ------------- 小红---czbk002---8000---2000 跟客户谈需求 ------------- 小红---czbk002---8000---2000 跟客户谈需求
09.24 抽象类中的小问题
1.一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
可以。不让创建对象。
2.abstract不能和哪些关键字共存
private 冲突
final 冲突
static 无意义
09.25 接口的引入
为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
09.26 接口的特点
接口特点:接口用关键字interface表示,格式:interface 接口名 {}
类实现接口用implements表示,格式:class 类名 implements 接口名 {}
接口不能实例化,按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
接口的子类要么是抽象类,要么重写接口中的所有抽象方法
09.27 接口的成员特点
成员变量:只能是常量,默认修饰符 public static final
构造方法:没有,因为接口主要是扩展功能的,而没有具体存在
成员方法:只能是抽象方法,默认修饰符 public abstract
09.28 类与类,类与接口,接口与接口的关系
类与类的关系:继承关系,只能单继承,但是可以多层继承
类与接口的关系:实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口
接口与接口的关系:继承关系,可以单继承,也可以多继承
09.29 抽象类和接口的区别
成员区别:
抽象类:成员变量,可以是变量也可以是常量。构造方法,有。成员方法,可以是抽象方法也可以是非抽象方法
接口:成员变量,只可以是常量。构造方法,没有。成员方法,只可以是抽象方法
关系区别:
类与类继承,单继承
类与接口实现,单实现,多实现
接口与接口继承,单继承,多继承
设计理念区别:
抽象类被继承体现的是:”is a”的关系。继承体系的共性功能
接口被实现体现的是:”like a”的关系。继承体系的扩展功能
09.30 猫狗案例加入跳高功能分析
猫狗案例,加入跳高的额外功能
分析:从具体到抽象
猫:姓名,年龄 吃饭,睡觉
狗:姓名,年龄 吃饭,睡觉
由于有共性功能,所以,我们抽取出一个父类:
动物:姓名,年龄 吃饭();睡觉(){}
猫:继承自动物
狗:继承自动物
跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口:跳高
部分猫:实现跳高
部分狗:实现跳高
实现:从抽象到具体
使用:使用具体类
09.31 猫狗案例加入跳高功能代码实现
1 //定义跳高接口 2 interface Jumpping 3 { 4 //跳高功能 5 public abstract void jump(); 6 } 7 8 //定义抽象类 9 abstract class Animal 10 { 11 //姓名 12 private String name; 13 //年龄 14 private int age; 15 16 public Animal() {} 17 18 public Animal(String name,int age) 19 { 20 this.name = name; 21 this.age = age; 22 } 23 24 public String getName() 25 { 26 return name; 27 } 28 29 public void setName(String name) 30 { 31 this.name = name; 32 } 33 34 public int getAge() 35 { 36 return age; 37 } 38 39 public void setAge(int age) 40 { 41 this.age = age; 42 } 43 44 //吃饭(); 45 public abstract void eat(); 46 47 //睡觉(){} 48 public void sleep() 49 { 50 System.out.println("睡觉"); 51 } 52 } 53 54 //具体猫类 55 class Cat extends Animal 56 { 57 public Cat(){} 58 59 public Cat(String name,int age) 60 { 61 super(name,age); 62 } 63 64 public void eat() 65 { 66 System.out.println("猫吃鱼"); 67 } 68 } 69 70 //具体狗类 71 class Dog extends Animal 72 { 73 public Dog(){} 74 75 public Dog(String name,int age) 76 { 77 super(name,age); 78 } 79 80 public void eat() 81 { 82 System.out.println("狗吃肉"); 83 } 84 } 85 86 //有跳高功能的猫 87 class JumpCat extends Cat implements Jumpping 88 { 89 public JumpCat() {} 90 91 public JumpCat(String name,int age) 92 { 93 super(name,age); 94 } 95 96 public void jump() 97 { 98 System.out.println("跳高猫"); 99 } 100 } 101 102 //有跳高功能的狗 103 class JumpDog extends Dog implements Jumpping 104 { 105 public JumpDog() {} 106 107 public JumpDog(String name,int age) 108 { 109 super(name,age); 110 } 111 112 public void jump() 113 { 114 System.out.println("跳高狗"); 115 } 116 } 117 class Demo 118 { 119 public static void main(String[] args) 120 { 121 //定义猫并测试 122 JumpCat jc = new JumpCat(); 123 jc.setName("哆啦A梦"); 124 jc.setAge(3); 125 System.out.println(jc.getName()+"---"+jc.getAge()); 126 jc.eat(); 127 jc.sleep(); 128 jc.jump(); 129 System.out.println("-----------------"); 130 131 JumpCat jc2 = new JumpCat("加菲猫",2); 132 System.out.println(jc2.getName()+"---"+jc2.getAge()); 133 jc2.eat(); 134 jc2.sleep(); 135 jc2.jump(); 136 } 137 }
运行结果:
哆啦A梦---3 猫吃鱼 睡觉 跳高猫 ------------ 加菲猫---2 猫吃鱼 睡觉 跳高猫
09.32 老师学生案例加入抽烟功能分析及代码实现
1 /* 2 老师和学生案例,加入抽烟的额外功能 3 分析:从具体到抽象 4 老师:姓名,年龄,吃饭,睡觉 5 学生:姓名,年龄,吃饭,睡觉 6 由于有共性功能,我们提取出一个父类,人类。 7 人类: 8 姓名,年龄 9 吃饭(); 10 睡觉(){} 11 抽烟的额外功能不是人或者老师,或者学生一开始就应该具备的,所以,我们把它定义为接口 12 部分老师抽烟:实现抽烟接口 13 部分学生抽烟:实现抽烟接口 14 实现:从抽象到具体 15 */ 16 //定义抽烟接口 17 interface Smoking 18 { 19 //抽烟的抽象方法 20 public abstract void smoke(); 21 } 22 23 //定义抽象人类 24 abstract class Person 25 { 26 //姓名 27 private String name; 28 //年龄 29 private int age; 30 31 public Person() {} 32 33 public Person(String name,int age) 34 { 35 this.name = name; 36 this.age = age; 37 } 38 39 public String getName() 40 { 41 return name; 42 } 43 44 public void setName(String name) 45 { 46 this.name = name; 47 } 48 49 public int getAge() 50 { 51 return age; 52 } 53 54 public void setAge(int age) 55 { 56 this.age = age; 57 } 58 59 //吃饭(); 60 public abstract void eat(); 61 62 //睡觉(){} 63 public void sleep() 64 { 65 System.out.println("睡觉"); 66 } 67 } 68 69 //具体老师类 70 class Teacher extends Person 71 { 72 public Teacher() {} 73 74 public Teacher(String name,int age) 75 { 76 super(name,age); 77 } 78 79 public void eat() 80 { 81 System.out.println("吃大白菜"); 82 } 83 } 84 85 //具体学生类 86 class Student extends Person 87 { 88 public Student() {} 89 90 public Student(String name,int age) 91 { 92 super(name,age); 93 } 94 95 public void eat() 96 { 97 System.out.println("吃红烧肉"); 98 } 99 } 100 101 //抽烟的老师 102 class SmokingTeacher extends Teacher implements Smoking 103 { 104 public SmokingTeacher() {} 105 106 public SmokingTeacher(String name,int age) 107 { 108 super(name,age); 109 } 110 111 public void smoke() 112 { 113 System.out.println("抽烟的老师"); 114 } 115 } 116 117 //抽烟的学生 118 class SmokingStudent extends Student implements Smoking 119 { 120 public SmokingStudent() {} 121 122 public SmokingStudent(String name,int age) 123 { 124 super(name,age); 125 } 126 127 public void smoke() 128 { 129 System.out.println("抽烟的学生"); 130 } 131 } 132 class Demo 133 { 134 public static void main(String[] args) 135 { 136 //测试学生 137 SmokingStudent ss = new SmokingStudent(); 138 ss.setName("小明"); 139 ss.setAge(27); 140 System.out.println(ss.getName()+"---"+ss.getAge()); 141 ss.eat(); 142 ss.sleep(); 143 ss.smoke(); 144 System.out.println("------------"); 145 146 SmokingStudent ss2 = new SmokingStudent("小强",30); 147 System.out.println(ss2.getName()+"---"+ss2.getAge()); 148 ss2.eat(); 149 ss2.sleep(); 150 ss2.smoke(); 151 } 152 }