• Java面向对象(三) 【面向对象深入:抽象类,接口,内部类等】


    面向对象(Object Oriented)

    1、抽象类
    抽象就是将拥有共同方法和属性的对象提取出来。提取后,重新设计一个更加通用、更加大众化的类,就叫抽象类。
    1)abstract 关键字修饰类、方法,即抽象类和抽象方法。
    2)抽象类可以有具体的方法,或者全部都是具体方法,但一个类中只要有一个抽象方法,那么这个类就是抽象类,并且必须用 abstract 修饰类。
    3)抽象类只能用来被继承,则子类必须实现抽象类中的全部抽象方法,否则子类也将是抽象类。抽象类也可主动继承实体类。
    4)抽象类不能实例化,即不能用 new 生成实例,所以只能作为父类使用。
    5)可以声明一个抽象类型的变量并指向具体子类的对象。
    6)抽象类可以实现接口中的方法。
    7)抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

     1 //抽象类Animal
     2 abstract class Animal {
     3     abstract public void shout();  //抽象方法
     4 }
     5 class Cat extends Animal { 
     6     //子类必须实现父类的抽象方法,否则编译错误
     7     public void shout() {
     8         System.out.println("喵喵喵!");
     9     }
    10     // 定义自己的特有方法
    11     public void CatchMouse(){
    12         System.out.println("抓老鼠ing....");
    13     }
    14 }
    15 //测试抽象类
    16 public class AbstractTest {
    17     public static void main(String[] args) {
    18     Animal animal = new Cat();// 这样new也是可以的
    19         Cat cat = new Cat();
    20         cat.shout();
    21         cat.seeDoor();
    22     }
    23 }
    AbstractTest Code

    疑问解答:
    1、抽象类中一定有抽象的方法?
    答:不对的。抽象类中可以有抽象方法,也可以没有抽象方法。
    2、有抽象方法的类,一定是抽象类?
    答:对的。如果一个类中包含了至少一个抽象方法,那么该类必须是抽象类。
    3、抽象类是否可以用final 修饰?
    答:不可以,final 的类不能当父类,abstract的类只能当父类。互斥的。不能同时使用。
    4、静态方法是否可以声明成抽象方法?
    答:不可以,static 和 abstract 也是互斥的。
    5、抽象方法是否可以使用 private 修饰?
    答:不可以。私有的方法不能子类继承,不能继承就不能重写。 抽象方法就是为了让子类实现重写的。互斥的。
    6、抽象类中定义的抽象方法,每一个抽象的方法都是定义了一个规则!!
    答:每一个抽象方法,都是父类给实现的子类定义的一个规则:子类在实现父类抽象方法的时候,不管子类实现的细节如何,但是对实现的功能是有要求的。
    7、抽象关键字不可以和那些关键字共存?
    private => 非法的修饰符组合: abstract和private(抽象需要被覆盖)
    static  => 非法的修饰符组合: abstract和static
    final   => 非法的修饰符组合: abstract和final
    8、抽象类和非抽象类的区别?
    1)抽象类不能被实例化,非抽象类可以实例化。

    2)抽象类必须是有子类的,不然没有定义该类的意义。非抽象类不一定了。如果final 修饰就一定没有子类。
    3)定义的方式不同。abstract 修饰抽象类。非抽象类不需要。
    4)抽象类中可以有抽象方法。非抽象类不可以有抽象方法的。
    2、接口(接口就是规范,定义的是一组规则。接口的出现将“多继承”通过另一种形式体现出来,即“多实现”)

    接口相关规则:
    • 接口中所有方法都是抽象的。
    • 即使没有显式的将接口中的成员用public标示,也是public访问类型的
    • 接口中变量默认用 public static final标示,所以接口中定义的变量就是全局静态常量。
    • 可以定义一个新接口,用extends去继承一个已有的接口
    • 可以定义一个类,用implements去实现一个接口中所有方法。
    • 可以定义一个抽象类,用implements去实现一个接口中部分方法。
    如何定义接口?

    如何实现接口?
    • 子类通过implements来实现接口中的规范
    • 接口不能创建实例,但是可用于声明引用变量类型。
    • 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
    • Java的类只支持单继承,接口支持多继承
    接口的多继承:接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。

    example

     1 package com.boom0831;
     2 /**
     3  * 测试接口和实现类
     4  * @author Administrator
     5  *
     6  */
     7 public class InterfaceTest {
     8 
     9     public static void main(String[] args) {
    10         Volant v = new Angel();
    11         v.fly();
    12         
    13         Honest h = new GoodMan();
    14         h.helpOther();
    15     }
    16 
    17 }
    18 /**
    19  * 飞行的接口
    20  * @author Administrator
    21  *
    22  */
    23 interface Volant{
    24     int FLY_HEIGHT = 10000;
    25     void fly();
    26 }
    27 // 善良的接口,天使接口
    28 interface Honest{
    29     void helpOther();
    30 }
    31 
    32 // 天使实现了飞行和善良的接口
    33 class Angel implements Volant,Honest{ // 实现类可以实现多个父接口
    34     // 实现飞行的接口
    35     @Override
    36     public void fly() {
    37         System.out.println("Angel.fly");
    38     }
    39     // 实现天使接口
    40     @Override
    41     public void helpOther() {
    42         System.out.println("Angel.helpOther");
    43     }
    44 }
    45 
    46 /**
    47  * 好人和坏人分别实现不同的接口
    48  * @author Administrator
    49  *
    50  */
    51 class GoodMan implements Honest{
    52     @Override
    53     public void helpOther() {
    54         System.out.println("GoodMan.Honest");
    55     }
    56 }
    57 
    58 class Birdman implements Volant{
    59     @Override
    60     public void fly() {
    61         System.out.println("Birdman.Volant");
    62     }
    63 }
    InterfaceTest Code

    example

     1 package com.boom0831;
     2 
     3 public class UsbInterface {
     4 
     5     public static void main(String[] args) {
     6         Usb u1 = new Fan();
     7         u1.run();
     8         Usb u2 = new Keyboard();
     9         u2.run();
    10         Usb u3 = new Mouse();
    11         u3.run();
    12     }
    13 
    14 }
    15 interface Usb{
    16     void run();
    17 }
    18 
    19 class Fan implements Usb{
    20     @Override
    21     public void run() {
    22         System.out.println("小风扇实现了USB接口。吹啊吹啊 我的骄傲放纵!");
    23     }
    24 }
    25 
    26 class Keyboard implements Usb{
    27     @Override
    28     public void run() {
    29         System.out.println("键盘实现了USB接口。开始疯狂的敲代码!funk!");
    30     }
    31 }
    32 
    33 class Mouse implements Usb{
    34     @Override
    35     public void run() {
    36         System.out.println("鼠标实现了USB接口。开始了蛇皮风骚走位!");
    37     }
    38 }
    UsbInterface Code

    example 升级版

     1 package com.boom0831;
     2 /**
     3  * UsbPlug多实现
     4  * @author Administrator
     5  *
     6  */
     7 public class ImplementTest {
     8 
     9     public static void main(String[] args) {
    10         Computer computer = new Computer();
    11         
    12         Mouse mouse = new Mouse();
    13         Keyboard keyboard = new Keyboard();
    14         computer.load(mouse);
    15         computer.load(keyboard);
    16         
    17         System.out.println("------ 扩展设备:小风扇 、 小台灯 ------");
    18         computer.load(new Fun());
    19         computer.load(new Light());
    20         
    21     }
    22 
    23 }
    24 
    25 //通过usb 接口 给 设备供电的规则
    26 interface UsbPlug{
    27     /**
    28      * 如何通过usb接口让设备运转起来的规则
    29      */
    30     void run();
    31 }
    32 
    33 //功能描述的是 插槽如何和usb连接 通电
    34 interface UsbSocket{
    35     /**
    36      * 插槽如何 连接 usb 插头,给插头通电
    37      * @param plug  被装备的 usb 插头
    38      */
    39     void load(UsbPlug plug);
    40 }
    41 
    42 //具有usb 功能的鼠标
    43 class Mouse implements UsbPlug{
    44     @Override
    45     public void run() {
    46         System.out.println("鼠标通过UsbPlug接口,鼠标通电成功,蛇皮走位操控电脑!");
    47     }
    48 }
    49 
    50 class Keyboard implements UsbPlug{
    51     @Override
    52     public void run() {
    53         System.out.println("键盘通过UsbPlug接口,键盘通电成功,疯狂敲代码到崩溃!");
    54         
    55     }
    56 }
    57 
    58 class Fun implements UsbPlug{
    59     @Override
    60     public void run() {
    61         System.out.println("小风扇通过UsbPlug接口,小风扇通电成功,吹啊吹啊 我的骄傲放纵!");
    62     }
    63 }
    64 
    65 class Light implements UsbPlug{
    66     @Override
    67     public void run() {
    68         System.out.println("小台灯通过UsbPlug接口,小台灯通电成功,发出奥特之光!");
    69     }
    70 }
    71 
    72  
    73 class Computer implements UsbSocket{
    74     // 电脑具有装载UsbPlug接口的功能
    75     public void load(UsbPlug plug){
    76         plug.run();
    77     }
    78 }
    Implement Code

    3、内部类
      在类内部定义的类为成员内部类,在方法里定义的类为局部内部类,被 static 修饰的为静态内部类。一个类中可有多个内部类。
    内部类的作用:
    1. 由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,在只为外部类提供服务的情况下可以优先考虑使用内部类。
    2. 使用内部类间接实现多继承:每个内部类都能独立地继承一个类或者实现某些接口,所以无论外部类是否已经继承了某个类或者实现了某些接口,对于内部类没有任何影响。
    .成员内部类(可以使用private、default、protected、public任意进行修饰。 类文件:外部类$内部类.class)

    a) 非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)
    i. 非静态内部类必须寄存在一个外部类对象里。如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。
    ii. 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。
    iii. 非静态内部类不能有静态方法、静态属性和静态初始化块。
    iv. 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。
    v. 成员变量访问要点:
    1. 内部类里方法的局部变量:变量名。
    2. 内部类属性:this.变量名。
    3. 外部类属性:外部类名.this.变量名。
    4.创建内部类格式:外部类.内部类  变量名 = new 外部类().new 内部类();

     1 package com.boom.innerclass;
     2 
     3 /**
     4  * 测试非静态内部类
     5  * 
     6  * @author Administrator
     7  *
     8  */
     9 public class InnerClass {
    10 
    11     public static void main(String[] args) {
    12         // 创建内部类对象
    13         Outer.Inner inner = new Outer().new Inner();
    14         inner.show();
    15     }
    16 
    17 }
    18 
    19 class Outer {
    20     private int age = 10;
    21 
    22     public void testOuter() {
    23 
    24     }
    25 
    26     // 非静态内部类Inner
    27     class Inner {
    28         int age = 30;
    29 
    30         public void show() {
    31             int age = 40;
    32             System.out.println("访问外部内成员变量age:" + Outer.this.age);// 10
    33             System.out.println("内部类内成员变量age:" + this.age); // 30
    34             System.out.println("局部变量age:" + age);//40
    35         }
    36     }
    37 }
    View Code

     b) 静态内部类  内部类前面被static关键字所修饰
    1. 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 静态内部类的实例方法不能直接访问外部类的实例方法。

    2. 静态内部类看做外部类的一个静态成员。 外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过 new 静态内部类()访问静态内部类的实例。

    c) 匿名内部类  适合那种只需要使用一次的类,一般Android使用的较多。
    1. 匿名内部类没有访问修饰符。
    2. 匿名内部类没有构造方法。因为它连名字都没有那又何来构造方法.
    • 只能实现一个接口,或者继承一个父类
    • 适合创建那种只需要一次使用的类,不能重复使用。比较常见的是在图形界面编程GUI里用得到。
    • 匿名内部类要使用外部类的局部变量,必须使用final修饰该局部变量
    d) 局部内部类:定义在方法内部的,作用域只限于本方法,称为局部内部类。
      局部内部类的的使用主要是用来解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类。局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法中被使用,出了该方法就会失效。局部内部类在实际开发中应用很少。


  • 相关阅读:
    第九天 how can I 坚持
    第八天 how can I 坚持
    第七天 how can I 坚持
    第六天 how can I 坚持
    第五天 how can I 坚持
    第四天 how can I 坚持
    第三天 how can I坚持
    第二天 how can I 坚持
    raw文件系统 分类: 生活百科 2013-11-09 14:12 448人阅读 评论(0) 收藏
    初次接触:DirectDraw 分类: VC++ DirectX 2013-11-09 11:16 950人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/cao-yin/p/9029702.html
Copyright © 2020-2023  润新知