第11章(下)--面向对象编程(高级特性)

1.  抽象类

 

当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract 来修饰该类就是抽象类。

 

 

 

      抽象类的介绍

 

1)      用abstract 关键字来修饰一个类时,这个类就叫抽象类
访问修饰符 abstract 类名{
}

2)      用abstract 关键字来修饰一个方法时,这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名(参数列表);

 

3)      抽象类的价值更多是在于设计,是设计者设计好后,让子类继承并实现抽象类(即:实现抽象类的抽象方法)

 

4)      抽象方法在编程中用的不是很多,但是在公司笔试时,却是考官比较爱问的知识点

 

 

 

   抽象类使用的注意事项和细节讨论

 

1)      抽象类不能被实例化  [举例]

2)      抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法 [举例]

3)      一旦类包含了abstract方法,则这个类必须声明为abstract [说明]

4)      abstract 只能修饰类和方法,不能修饰属性和其它的。[说明]

5)      抽象类可以有任意成员【因为抽象类还是类】,比如:非抽象方法、构造器、静态属性等等 [举例]

6)      抽象方法不能有主体,即不能实现.如图所示

7)      如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。[举例 A类,B类,C类]

8)      抽象方法不能使用privatefinal static来修饰,因为这些关键字都是和重写相违背的。说明: static关键字是不和重写相关,static方法不能重写

 

  • 和前面一样,多态在抽象类上也体现在

多态数组【存放不同的子类对象, Dog和Cat】

多态参数【接收不同的子类对象】

 

 

 1 public class AbstractPolyDemo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         
 6         Animal03 animals[] = new Animal03[2];
 7         animals[0] = new Cat03();
 8         animals[1] = new Dog03();
 9         
10         //抽象类体现出多态数组
11         for (int i = 0; i < animals.length; i++) {
12             animals[i].eat();
13             show(animals[i]);
14         }
15 
16     }
17     
18     //多态参数
19     public static void show(Animal03 animal) {
20         if (animal instanceof Cat03) {
21             Cat03 cat = (Cat03)animal;
22             cat.catchMouse();
23         } else if (animal instanceof Dog03) {
24             Dog03 dog = (Dog03)animal;
25             dog.watchDoor();
26         }
27     }
28 
29 }
30 
31 abstract class Animal03 {
32     
33     abstract public void eat();
34 }
35 
36 class Cat03 extends Animal03 {
37 
38     @Override
39     public void eat() {
40         // TODO Auto-generated method stub
41         System.out.println("小猫喜欢吃<・)))><<");
42     }
43     
44     public void catchMouse() {
45         System.out.println("小猫抓老鼠");
46     }
47     
48 }
49 
50 class Dog03 extends Animal03 {
51 
52     @Override
53     public void eat() {
54         // TODO Auto-generated method stub
55         System.out.println("小狗喜欢吃骨头~~");
56     }
57     
58     public void watchDoor() {
59         System.out.println("小狗看门~~");
60     }
61     

 

 

        抽象类最佳实践-模板设计模式

1.1.1       基本介绍

 

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现

编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。

   

     最佳实践

 

设计一个抽象类(Template),能完成如下功能:

1)      编写方法caleTime() ,可以计算某段代码的耗时时间

2)      编写抽象方法code()

3)      编写一个子类Sub,继承抽象类Template,并实现code方法。

4)      编写一个测试类TestTemplate,看看是否好用。

 

 1 public class AbstractTemplateDemo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         Sub sub = new Sub();
 6         sub.caleTime();
 7         
 8         Sub2 sub2 = new Sub2();
 9         sub2.caleTime();
10 
11     }
12 
13 }
14 
15 // 通过抽象类开发要给 模板设计模式
16 
17 abstract class Template {
18 
19     abstract public void code(); // code不确定.
20     // 统计code() 方法执行时间
21 
22     public void caleTime() {
23         // 1先得到当前的时间(毫秒)
24         long nowTime = System.currentTimeMillis();
25         code();
26         // 2得到执行后的时间
27         long endTime = System.currentTimeMillis();
28         System.out.println("执行代码时间为=" + (endTime - nowTime));
29     }
30 }
31 
32 class Sub extends Template { // 张三
33 
34     @Override
35     public void code() {
36         // TODO Auto-generated method stub
37         // 测试 hello, 拼接 10000次
38         String str = "hello";
39         for (int i = 0; i < 20000; i++) {
40             str += "jack" + i;
41         }
42 
43     }
44 
45 }
46 
47 class Sub2 extends Template {// 李四
48 
49     @Override
50     public void code() {
51         // TODO Auto-generated method stub
52         // 测试 hello, 拼接 10000次
53         StringBuilder str = new StringBuilder("hello");
54         for (int i = 0; i < 20000; i++) {
55             str.append("jack" + i);
56         }
57 
58     }
59 
60 }

  标准 服务 产品 项目

 

2.接口

 

接口快速入门

 1 public class InterfaceDemo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         Computer computer = new Computer();
 6         Phone phone = new Phone();
 7         Camera camera = new Camera();
 8         
 9         computer.work(phone); //这里因为Phone已经实现了UsbInterface
10         computer.work(camera);//这里因为Camera已经实现了UsbInterface
11 
12     }
13 
14 }
15 
16 
17 class Computer {
18     public void work(UsbInterface usbInterace) {
19         //...
20         usbInterace.start();
21         usbInterace.start();
22     }
23 }
24 
25 //定义给接口,要求各个类去实现
26 interface UsbInterface {
27     //定一些规范, 规范可以简单的理解就是方法(没有实现的方法)
28     public void start();
29     public void stop();
30 }
31 
32 class Camera implements UsbInterface {
33 
34     @Override
35     public void start() {
36         // TODO Auto-generated method stub
37         System.out.println("相机开始工作~~");
38     }
39 
40     @Override
41     public void stop() {
42         // TODO Auto-generated method stub
43         System.out.println("相机结束工作~~");
44         
45     }
46     
47 }
48 
49 class Phone implements UsbInterface {
50 
51     @Override
52     public void start() {
53         // TODO Auto-generated method stub
54         System.out.println("手机开始工作~~");
55         
56     }

接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。

  • 语法:

interface 接口名{

   //属性

   //抽象方法

}

class 类名 implements 接口{

      自己属性;

      自己方法;

      实现的接口的抽象方法

}

  • 小结:接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口里的所有方法都

没有方法体【jdk7.0以前】。接口体现了程序设计的多态和高内聚低偶合的设计思想。高内聚坏了不会影响到别人,低耦合两个模块耦合性很低

  • 特别说明:Jdk1.8后接口类可以有静态方法,默认方法,也就是说接口中可以有方法的

具体实现, 这个放在jdk8新特性说明

接口应用场景

 

 

 

 1 public class InterfaceJdbcTest {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         JdbcInterface jdbc = new MySqlDB();
 6         jdbc.connect();
 7         System.out.println(jdbc.operate());
 8         jdbc.close();
 9         
10         jdbc = new DB2();
11         
12         jdbc.connect();
13         System.out.println(jdbc.operate());
14         jdbc.close();
15 
16     }
17 
18 }
19 
20 
21 interface JdbcInterface {
22     public void connect();
23     public String operate();
24     public void close();
25 }
26 
27 class MySqlDB implements JdbcInterface {
28 
29     @Override
30     public void connect() {
31         // TODO Auto-generated method stub
32         System.out.println("连接mysql");
33     }
34 
35     @Override
36     public String operate() {
37         // TODO Auto-generated method stub
38         return "操作mysql";
39     }
40 
41     @Override
42     public void close() {
43         // TODO Auto-generated method stub
44         System.out.println("关闭mysql");
45     }
46     
47 }
48 
49 class DB2 implements JdbcInterface {
50 
51     @Override
52     public void connect() {
53         // TODO Auto-generated method stub
54         System.out.println("连接DB2");
55         
56     }
57 
58     @Override
59     public String operate() {
60         // TODO Auto-generated method stub
61         return "操作db2成功";
62     }
63 
64     @Override
65     public void close() {
66         // TODO Auto-generated method stub
67         System.out.println("关闭db2");
68     }
69     
70 }

 

 

     注意事项和细节

 

1)      接口不能被实例化

2)      接口中所有的方法都public或者default 的抽象方法,图示:

3)      一个普通类实现接口,就必须将该接口的所有方法都实现。

4)      抽象类实现接口,可以不用实现接口的方法。

5)      一个类可以实现多个接口 [举例]

6)      接口中的属性,只能是常量,而且是 public static final 修饰符。比如:
int a=1; 实际上是 public static final int a=1; (必须初始化)

7)      接口中常量的访问形式: 接口名.变量名

8)      一个接口不能继承其它的类,但是可以继承多个别的接口 [举例]

9)      接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的。

 1 public class ExtendsVSImplement {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         
 6         LittleMonkey littleMonkey = new LittleMonkey("悟空", (short)10);
 7         littleMonkey.climbing();
 8         littleMonkey.fly();
 9         littleMonkey.swim();
10         
11         Monkey m = littleMonkey;
12         m.climbing();
13         IBirdable a = littleMonkey;
14         a.fly();
15         IFishable b = littleMonkey;
16         b.swim();
17         
18         
19 
20     }
21 
22 }
23 
24 //猴子类
25 class Monkey {
26     private String name;
27     private short age;
28     
29     
30     
31     public Monkey(String name, short age) {
32         super();
33         this.name = name;
34         this.age = age;
35     }
36 
37     public void climbing() {
38         System.out.println(name + " 能爬树~~");
39     }
40 
41     public String getName() {
42         return name;
43     }
44 
45     public void setName(String name) {
46         this.name = name;
47     }
48 
49     public short getAge() {
50         return age;
51     }
52 
53     public void setAge(short age) {
54         this.age = age;
55     }
56     
57     
58 }
59 
60 interface IBirdable {
61     public void fly();
62 }
63 interface IFishable {
64     public void swim();
65 }
66 
67 class LittleMonkey extends Monkey implements IBirdable,IFishable {
68     
69     
70     public LittleMonkey(String name, short age) {
71         // TODO Auto-generated constructor stub
72         super(name, age);
73     }
74     
75     public void fly() {
76         System.out.println(getName() + " 通过学习会飞翔~~");
77     }
78     public void swim() {
79         System.out.println(getName() + " 通过学习会游泳~~");
80     }
81 }

 

3.接口和继承比较 

 

实现接口可以看作是对继承的一种补充

java的继承是单继承,也就是一个类最多只能有一个父类,这种单继承的机制可保证类的

纯洁性,比c++中的多继承机制简洁。但是不可否认,对子类功能的扩展有一定影响.所以

我们认为: 实现接口可以看作是对 继承的一种补充

 

 

  • 接口和继承解决的问题不同

 

继承的价值主要在于:解决代码的复用性和可维护性。

接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法。

 

 

  • 接口比继承更加灵活

 

接口比继承更加灵活,继承是满足 is - a的关系,而接口只需满足 like - a的关系。

 

  • 接口在一定程度上实现代码解耦

 

 

 

 

 

 

 接口练习:

 

4.内部类

 

1.1.1       基本介绍

 

一个类的内部又完整的嵌套了另一个完整的类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员

类的五大成员是哪些?[属性,方法,构造器,代码块,内部类]】,内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

1.1.1       基本语法

 

class Outer{ //外部类
               class Inner{ //内部类

              }
       }
       class Other{ //外部其他类
       }

 

1.1.1       内部类的分类

 

 

  • 定义在外部类的成员位置上:

1) 成员内部类(没用static修饰)

2) 静态内部类(使用static修饰)

 

 

  • 定义在外部类局部位置上(比如方法内):

1) 局部内部类(有类名)

2) 匿名内部类(没有类名)

 

1.1.2       成员内部类的使用

 

说明:成员内部类是定义在外部类的成员位置,并且没有static修饰。

1) 可以直接访问外部类的所有成员,包含私有的

2) 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员.

3) 作用域
   和外部类的其他成员一样,为整个类体, 比如前面案例,在外部类的成员方法中创建成员内部类对象,再调用方法

4) 成员内部类---访问---->外部类(比如:属性)  [访问方式:直接访问] (说明)

5) 成员外部类---访问------>内部类 (说明)
           访问方式:创建对象,再访问

6) 外部其他类---访问---->成员内部类

 

7) 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问

 

 

 

 

 

 

1.1.1       静态内部类的使用

 

1) 说明:静态内部类是定义在外部类的成员位置,并且有static修饰

2) 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

3) 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员。

4) 作用域
       同其他的成员,为整个类体

5) 静态内部类---访问---->外部类(比如:静态属性)  [访问方式:直接访问所有静态成员]

6) 外部类---访问------>静态内部类 访问方式:创建对象,再访问

7) 外部其他类---访问----->静态内部类

8) 如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.成员)去访问

 

 

 

posted @ 2020-06-21 09:05  --学无止境--  阅读(246)  评论(0)    收藏  举报