1 package cn.temptation;
2
3 public class Sample01 {
4 public static void main(String[] args) {
5 // 仔细想一想,Animal应该是一个抽象的概念,相对于Animal来说,狗才是具体的概念
6 // Animal的行为也应该算是一个抽象的行为
7
8 // Java中对于这些抽象的概念或是抽象的行为,提供了一个关键字 abstract 来进行修饰
9
10 // 关键字 abstract用在类上,类称为抽象类:abstract class 类名
11 // 关键字 abstract用在方法上,方法称为抽象方法:abstract 返回类型 方法名(参数列表)
12
13 // 抽象类不能进行实例化
14 // 原因:既然这个Animal类都是抽象的概念了,自然无法具体的创建出一个对象来,所以不能被实例化
15 // 语法错误:Cannot instantiate the type Animal
16 // Animal animal = new Animal();
17
18 // 抽象类不能直接实例化使用,但是可以通过继承使用,使用多态写法
19 // Animal animal = new Dog();
20 // 对于子类的成员方法,编译看赋值号左边,执行看赋值号右边
21 // animal.eat();
22 }
23 }
24
25 //// 抽象类
26 //abstract class Animal {
27 // // 成员方法
28 // // 语法错误:Abstract methods do not specify a body 抽象方法没有方法体
29 //// public abstract void eat() {
30 //// System.out.println("动物会吃");
31 //// }
32 //
33 // // 成员方法上使用了abstract,就变成了一个抽象成员方法
34 // // 没有方法体,意味着没有具体的实现,只是定义
35 // public abstract void eat();
36 //}
37 //
38 //// 具体实现子类
39 //class Dog extends Animal {
40 // @Override
41 // public void eat() {
42 // System.out.println("狗会吃");
43 // }
44 //}
1 package cn.temptation;
2
3 public class Sample02 {
4 public static void main(String[] args) {
5 // 抽象类 和 抽象成员方法的特点:
6 // 1、抽象类中可以有抽象的成员方法,也可以有非抽象的成员方法
7 // 2、只要类中有抽象的成员方法,该类就必须得是抽象类
8 // 3、抽象的成员方法没有方法体,只有小括号没有大括号,但是有分号作为结尾
9 // 4、抽象类不能被实例化,因为它被修饰为抽象的
10 // 5、抽象类可以有构造函数;虽然其构造函数不是用来做实例化的操作,但是可以提供给其子类创建对象时使用
11 // 6、抽象类的子类也可以是一个抽象类
12 // 7、不论抽象类中的成员方法是否为抽象的,只要类是抽象的,就不能实例化,也就不能使用对象名.成员方法来进行调用
13 }
14 }
15
16 // 抽象父类
17 abstract class Animal {
18 // 构造函数
19 public Animal() {
20 System.out.println("无参构造函数");
21 }
22
23 // 成员方法
24 // 抽象的成员方法
25 public abstract void eat();
26
27 // 非抽象的成员方法
28 public void sleep() {
29 System.out.println("动物能睡觉");
30 }
31 }
32
33 // 抽象子类
34 abstract class Dog extends Animal {
35
36 }
37
38 // 抽象子类的具体实现的孙类
39 class ChineseDog extends Dog {
40 @Override
41 public void eat() {
42 System.out.println("中国狗会吃");
43 }
44 }
45
46 // The abstract method test in type Demo can only be defined by an abstract class
47 //class Demo {
48 // // 抽象的成员方法
49 // public abstract void test();
50 //}
1 package cn.temptation;
2
3 public class Sample03 {
4 public static void main(String[] args) {
5 // 抽象类成员的使用问题:
6 // 1、成员变量:可以是变量,也可以是自定义常量
7 // 2、构造函数:构造函数不是用来做实例化的,但是是提供给子类使用的
8 // 3、成员方法:可以是抽象的,也可以是非抽象的
9 // 抽象的成员方法:强制具体实现子类实现父类的抽象成员方法
10 // 非抽象的成员方法:子类可以重写、也可以不重写
11
12 Human human = new Man();
13 System.out.println(human.i);
14 System.out.println(human.X);
15 }
16 }
17
18 // 抽象类
19 abstract class Human {
20 // 成员变量
21 public int i = 2;
22 public final int X = 3;
23
24 // 构造函数(无参)
25 public Human() {
26 System.out.println("无参构造函数");
27 }
28
29 // 构造函数不能使用abstract修饰
30 // 语法错误:Illegal modifier for the constructor in type Human; only public, protected & private are permitted
31 // public abstract Human();
32
33 // 构造函数(有参)
34 public Human(int i) {
35 this.i = i;
36 System.out.println(i);
37 }
38
39 // 成员方法
40 // 抽象的成员方法
41 public abstract void eat();
42
43 // 非抽象的成员方法
44 public void sleep() {
45 System.out.println("人能睡觉");
46 }
47 }
48
49 // 具体实现子类
50 class Man extends Human {
51 // 构造函数
52 public Man() {
53 super(99);
54 }
55
56 // 成员方法
57 // 不重写就会生成语法错误
58 // 语法错误:The type Man must implement the inherited abstract method Human.eat() Sample03.java /Day20170302_OOP/src/cn/temptation line 48 Java Problem
59 // 重写抽象的成员方法
60 public void eat() {
61
62 }
63 }
1 package cn.temptation;
2
3 public class Sample04 {
4 public static void main(String[] args) {
5 // 调用抽象类的静态成员变量 和 静态成员方法,使用类名.静态成员,无视该类是否为抽象类
6 // System.out.println(Phone.number);
7 // Phone.call();
8 }
9 }
10
11 abstract class Phone {
12 // 静态成员变量
13 // static int number = 110;
14
15 // 静态成员方法
16 // static void call() {
17 // System.out.println("打电话");
18 // }
19
20 // 抽象的成员方法
21 public abstract void method1();
22
23 // private 和 abstract同时修饰,语法错误。
24 // 理解:private要求的是私有的,而abstract提出抽象的概念,需要后代去做实现,所以语义上是矛盾的
25 // 语法错误:The abstract method method2 in type Phone can only set a visibility modifier, one of public or protected
26 // private abstract void method2();
27
28 // final 和 abstract同时修饰,语法错误。
29 // 理解:final要求的是子类不能重写父类的成员方法,而abstract提出抽象的概念,需要后代去做实现,所以语义上是矛盾的
30 // 语法错误:The abstract method method3 in type Phone can only set a visibility modifier, one of public or protected
31 // final abstract void method3();
32
33 // static 和 abstract同时修饰,语法错误。
34 // 理解:static要求的是对象们(类的)的成员方法,而abstract提出抽象的概念(不是具体的),所以语义上是矛盾的
35 // 语法错误:The abstract method method4 in type Phone can only set a visibility modifier, one of public or protected
36 // static abstract void method4();
37 }
1 package cn.temptation;
2
3 public class Sample05 {
4 public static void main(String[] args) {
5 // 需求:使用学过的知识点实现
6 // 东汉公司的员工都不睡觉
7 // 1、东汉公司的码农 吕布 是公司的员工,他写代码、打游戏,拿很少的薪水(1680)
8 // 2、东汉公司的经理 貂蝉 也是公司的员工,她做管理、听音乐,拿很多的薪水(20000)
9
10 Staff.companyName = "东汉";
11
12 Staff staff1 = new Programmer("吕布", 1680);
13 System.out.println("姓名为:" + staff1.getName() + ",薪资为:" + staff1.getSalary() + ",公司名为:" + Staff.companyName);
14 staff1.nosleep();
15 staff1.work();
16 ((Programmer)staff1).playGame();
17
18 Staff staff2 = new Manager();
19 staff2.setName("貂蝉");
20 staff2.setSalary(20000);
21 System.out.println("姓名为:" + staff2.getName() + ",薪资为:" + staff2.getSalary() + ",公司名为:" + Staff.companyName);
22 staff2.nosleep();
23 staff2.work();
24 ((Manager)staff2).listenMusic();
25 }
26 }
27
28 /**
29 * 抽象类:员工类
30 */
31 abstract class Staff {
32 // 成员变量
33 // 名字
34 private String name;
35 // 薪资
36 private int salary;
37 // 公司名
38 public static String companyName;
39
40 // 构造函数(无参)
41 public Staff() {
42
43 }
44
45 public Staff(String name, int salary) {
46 super();
47 this.name = name;
48 this.salary = salary;
49 }
50
51 // 成员方法
52 public String getName() {
53 return name;
54 }
55
56 public void setName(String name) {
57 this.name = name;
58 }
59
60 public int getSalary() {
61 return salary;
62 }
63
64 public void setSalary(int salary) {
65 this.salary = salary;
66 }
67
68 // 自定义成员方法
69 /**
70 * 抽象成员方法:工作
71 * 等着具体实现子类去进行实现
72 */
73 public abstract void work();
74
75 /**
76 * 非抽象成员方法:不睡觉
77 * 不想被子类重写,可以使用final进行修饰
78 */
79 public final void nosleep() {
80 System.out.println("不睡觉");
81 }
82 }
83
84 /**
85 * 子类:程序员类
86 */
87 class Programmer extends Staff {
88 // 成员变量
89
90 // 构造函数
91 public Programmer() {
92 super();
93 }
94
95 public Programmer(String name, int salary) {
96 super(name, salary);
97 }
98
99 // 成员方法
100 @Override
101 public void work() {
102 System.out.println("写代码");
103 }
104
105 public void playGame() {
106 System.out.println("打游戏");
107 }
108 }
109
110 /**
111 * 子类:经理类
112 */
113 class Manager extends Staff {
114 // 成员方法
115 @Override
116 public void work() {
117 System.out.println("做管理");
118 }
119
120 public void listenMusic() {
121 System.out.println("听音乐");
122 }
123 }
1 package cn.temptation;
2
3 public class Sample06 {
4 public static void main(String[] args) {
5 // Bird bird1 = new Eagle(); // 老鹰是一种鸟
6 // bird1.fly();
7 //
8 // Bird bird2 = new Sparrow(); // 麻雀是一种鸟
9 // bird2.fly();
10 //
11 // Bird bird3 = new Plane(); // 飞机是一种鸟
12 // bird3.fly();
13 }
14 }
15
16 //// 抽象类:鸟类
17 //abstract class Bird {
18 // // 抽象方法:飞行
19 // public abstract void fly();
20 //}
21 //
22 //// 具体子类:老鹰类
23 //class Eagle extends Bird {
24 // @Override
25 // public void fly() {
26 // System.out.println("老鹰的飞行");
27 // }
28 //}
29 //
30 //// 具体子类:麻雀类
31 //class Sparrow extends Bird {
32 // @Override
33 // public void fly() {
34 // System.out.println("麻雀的飞行");
35 // }
36 //}
37 //
38 //// 为了让飞机能飞行,强行让飞机从抽象父类鸟类进行继承,这样很别扭
39 //// 究其原因,因为子类继承父类,得到了父类的特征和行为(非私有的),这是一种先天的联系
40 //// 但是,在现实的世界中,除了描述先天上的联系,还有描述后天的关联
41 //// 这里的飞机会飞行,这不是先天上的天赋,而是后天具有的能力
42 //// 对于这些后天具备的能力,还去使用描述先天联系的继承去实现,就显得别扭了
43 //
44 //// 对于描述后天具备的能力,Java中提供了 接口(interface) 机制
45 //
46 //// 具体子类:飞机类
47 //class Plane extends Bird {
48 // @Override
49 // public void fly() {
50 // System.out.println("飞机的飞行");
51 // }
52 //}
1 package cn.temptation;
2
3 public class Sample07 {
4 public static void main(String[] args) {
5 // 接口:描述事物具有的能力
6
7 // 格式:interface 接口名 { ... }
8
9 // 接口的实现形式: class 类名 implements 接口名 { .... }
10
11 // 注意:
12 // 1、接口不能实例化
13 // 2、如何使用接口?
14 // A:通过实现接口的类使用接口
15 // B:重写接口中定义的成员方法(类似抽象类的实现子类中的重写)
16
17 // 语法错误:Cannot instantiate the type Ability
18 // Ability ability = new Ability();
19
20 // 常规写法(类的实例化)
21 // Plane plane = new Plane();
22 // plane.fly();
23
24 // 多态写法
25 // Ability plane = new Plane(); // 飞机具备能力
26 // plane.fly();
27
28 // 关于多态及其重写使用的场合:
29 // 1、非抽象类继承后的多态(不常见)
30 // 2、抽象类继承后的多态(常见)
31 // 3、接口实现后的多态(常见)
32 }
33 }
34
35 //// 接口:能力接口
36 //interface Ability {
37 // // 接口中的方法没有方法体
38 // // 语法错误:Abstract methods do not specify a body
39 //// public void fly() {
40 ////
41 //// }
42 //
43 // // 接口中的方法必须是抽象的
44 // public abstract void fly();
45 //}
46 //
47 //// 具体的飞机类 实现 能力接口
48 //class Plane implements Ability {
49 // @Override
50 // public void fly() {
51 // System.out.println("飞机 的飞行");
52 // }
53 //}
1 package cn.temptation;
2
3 public class Sample08 {
4 public static void main(String[] args) {
5 // 接口的成员:
6 // 1、成员变量:
7 // 接口中的成员变量支持的修饰符:public static final 数据类型 成员变量名
8 // 通过对接口的字节码文件的反编译,发现接口中的成员变量的修饰符都是public static final修饰的,也就是这些成员变量都是接口的自定义常量
9 // 2、构造函数
10 // 接口不能有构造函数(接口不能实例化)
11 // 3、成员方法
12 // 接口中的方法必须是抽象的,不能是非抽象的
13 // 接口中的所有方法(都是抽象方法)必须要在实现类中进行实现
14 Test obj = new TestImpl();
15 System.out.println(obj.i);
16 System.out.println(obj.j);
17 System.out.println(obj.k);
18
19 // 语法错误:The final field Test.i cannot be assigned
20 // obj.i = 99;
21
22 // 注意:"不能实例化的就一定没有构造函数"这种说法对不对? 答:不对,例如:抽象类
23 }
24 }
25
26 // 接口
27 interface Test {
28 // 成员变量
29 public int i = 2;
30 public final int j = 4;
31 public static final int k = 6;
32 // 语法错误:Illegal modifier for the interface field Test.x; only public, static & final are permitted
33 // private int x = 99;
34
35 // 构造函数
36 // 语法错误:Interfaces cannot have constructors
37 // public Test() {
38 //
39 // }
40
41 // 成员方法
42 // 非抽象的成员方法
43 // 语法错误:Abstract methods do not specify a body
44 // public void method() {
45 //
46 // }
47
48 // 抽象的成员方法
49 public abstract void method1();
50 // 语法错误:Illegal modifier for the interface method method2; only public, abstract, default, static and strictfp are permitted
51 // private abstract void method2();
52 }
53
54 // 接口的实现类
55 class TestImpl implements Test {
56 @Override
57 public void method1() {
58
59 }
60 }
1 package cn.temptation;
2
3 public class Sample09 {
4 public static void main(String[] args) {
5 // 1、类 和 类之间的关系
6 // 类和类之间可以是继承的关系(extends 关键字 inheritance)
7 // Java中的继承(针对类)是单继承,可以有继承链
8
9 // 2、类 和 接口之间的关系
10 // 类和接口之间是实现的关系(implements 关键字 implement)
11 // Java中的实现可以是单实现(具备某一种能力),也可以是多实现(具备多种能力)
12 // 注意:类与接口之间是实现的关系,没有继承的关系
13
14 // 3、接口 和 接口之间的关系
15 // 接口 和 接口之间可以是单继承,也可以是多继承
16 // 注意:接口不能实现另一个接口,因为接口定义的是规范,不是实现
17
18 // 面试题:
19 // Java语言是单继承、多实现的(×)
20 // 答:对于类,是单继承、多实现的;对于接口,是可以单继承,也可以多继承,但是不能实现其他接口或类
21 }
22 }
23
24 class GrandFather {
25
26 }
27
28 class Father extends GrandFather {
29
30 }
31
32 class Mother {
33
34 }
35
36 // 语法错误:Syntax error on token ",", . expected
37 //class Son extends Father, Mother {
38 // 语法错误:The type Eat cannot be the superclass of Son; a superclass must be a class
39 //class Son extends Eat {
40 class Son extends Father implements Eat, Sleep {
41
42 }
43
44 interface Eat {
45
46 }
47
48 interface Sleep {
49
50 }
51
52 // 接口可以多继承
53 //interface Lazy extends Eat, Sleep {
54 //
55 //}
56
57 // 语法错误:Syntax error on token "implements", extends expected
58 //interface Lazy implements Eat {
59 //interface Lazy implements Sleep {
60 //}
1 package cn.temptation;
2
3 public class Sample10 {
4 public static void main(String[] args) {
5 // 抽象类 和 接口的区别
6 /*
7 * 1、成员上的区别:
8 * 抽象类:
9 * A:成员变量:可以是变量,也可以是常量
10 * B:构造函数:有,但是不能实例化,只能供子类调用
11 * C:成员方法:可以有抽象的成员方法,也可以有非抽象的成员方法
12 *
13 * 接口:
14 * A:成员变量:都是常量(自定义常量)
15 * B:构造函数:没有构造函数
16 * C:成员方法:都是抽象的成员方法
17 *
18 * 2、关系上的区别:
19 * 类和类:单继承
20 * 类和接口:类可以是单实现接口,也可以是多实现接口
21 * 接口和接口:接口可以是单继承接口,也可以是多继承接口
22 *
23 * 3、设计意图上的区别:
24 * 抽象类:描述的是先天的天赋,有着抽象的概念、抽象的行为和具体实现子类是继承的关系,对于继承的具体实现子类来说描述了"is a(an)"的含义
25 * 抽象类中定义的成员是这些子类以及它们的后代共有的特征和行为(且不好具体描述)
26 * 接口:描述的是后天培养的、具备的能力,供类实现或是给其他接口继承,描述的是"like a(an)"或"as a(an)"的含义
27 * 接口中定义的是被实现的类需要扩展的功能
28 */
29
30 // 【面向对象设计原则之一:"开闭原则"-----"对扩展开放,对修改封闭"】
31 // 换句话说,在面向对象的设计中,建议多使用接口,少使用继承
32 // 对于接口,应该理解其"规范性、强制性"的特点
33 }
34 }
35
36 // 接口:能力接口
37 interface Ability {
38 // 接口中的方法必须是抽象的
39 public abstract void fly();
40 }
41
42 class Plane implements Ability {
43 // 实现了Ability接口,具备了接口定义的能力(方法)
44 @Override
45 public void fly() {
46 System.out.println("飞机能飞");
47 }
48 }
1 package cn.temptation;
2
3 public class Sample11 {
4 public static void main(String[] args) {
5 // 需求:使用学过的知识(例如:抽象类、接口等)实现如下功能
6 // 1、吕布是个体育系的男学生,20岁,学习Java,会打篮球(因为是体育系的)
7 // 2、貂蝉是个音乐系的女学生,16岁,学习乐理,会弹棉花(因为是音乐系的)
8
9 Student student1 = new PE("吕布", 20, "男");
10 student1.study("Java");
11 ((PE)student1).doSport("篮球");
12
13 Student student2 = new MusicalStudent("貂蝉", 16, "女");
14 student2.study("乐理");
15 ((MusicalStudent)student2).doEquipment("棉花");
16 }
17 }
18
19 // 抽象类:学生类
20 abstract class Student {
21 // 成员变量
22 // 姓名
23 private String name;
24 // 年龄
25 private int age;
26 // 性别
27 private String gender;
28 // 系别
29 public static String dept = "";
30
31 // 构造函数
32 public Student() {
33 super();
34 }
35
36 public Student(String name, int age, String gender, String dept) {
37 super();
38 this.name = name;
39 this.age = age;
40 this.gender = gender;
41 Student.dept = dept;
42
43 System.out.println("姓名为:" + this.name + ",年龄为:" + this.age + ",性别为:" + this.gender + ",系别为:" + Student.dept);
44 }
45
46 // 成员方法
47 public String getName() {
48 return name;
49 }
50
51 public void setName(String name) {
52 this.name = name;
53 }
54
55 public int getAge() {
56 return age;
57 }
58
59 public void setAge(int age) {
60 this.age = age;
61 }
62
63 public String getGender() {
64 return gender;
65 }
66
67 public void setGender(String gender) {
68 this.gender = gender;
69 }
70
71 // 自定义的成员方法
72 // 考虑到学生先天的天赋行为有学习,所以在抽象类中制作一个抽象方法study
73 public abstract void study(String course);
74 }
75
76 /**
77 * 具体实现子类:体育系学生
78 */
79 class PE extends Student implements Sport {
80 // 成员变量
81 // 考虑到系别是子类的特征,所以定义为static
82 public static String dept = "体育系";
83
84 // 构造函数
85 public PE() {
86 super();
87 }
88
89 public PE(String name, int age, String gender) {
90 super(name, age, gender, PE.dept);
91 }
92
93 // 成员方法
94 @Override
95 public void study(String course) {
96 System.out.println("学习" + course);
97 }
98
99 @Override
100 public void doSport(String sportName) {
101 System.out.println("做" + sportName + "运动");
102 }
103 }
104
105 /**
106 * 具体实现子类:音乐系学生
107 */
108 class MusicalStudent extends Student implements Equipment {
109 // 成员变量
110 // 考虑到系别是子类的特征,所以定义为static
111 public static String dept = "音乐系";
112
113 // 构造函数
114 public MusicalStudent() {
115 super();
116 }
117
118 public MusicalStudent(String name, int age, String gender) {
119 super(name, age, gender, MusicalStudent.dept);
120 }
121
122 // 成员方法
123 @Override
124 public void study(String course) {
125 System.out.println("学习" + course);
126 }
127
128 @Override
129 public void doEquipment(String equipmentName) {
130 System.out.println("演奏" + equipmentName + "器械");
131 }
132 }
133
134 // 运动能力接口
135 interface Sport {
136 public abstract void doSport(String sportName);
137 }
138
139 // 器械能力接口
140 interface Equipment {
141 public abstract void doEquipment(String equipmentName);
142 }