• 第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) 如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.成员)去访问

     

  • 相关阅读:
    ES 2016+
    git-svn for mac
    Linux系统下安装rz/sz命令及使用说明
    Nginx location指令匹配顺序规则
    nginx修改配置后不生效的问题
    ssh and scp从远程服务器下载文件
    安装yii2 框架遇到的问题
    php添加openssl扩展
    GitHub Token for composer
    centos7+nginx+php+mysql环境搭建
  • 原文地址:https://www.cnblogs.com/-xuewuzhijing-/p/13171395.html
Copyright © 2020-2023  润新知