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)抽象类不能被实例化,非抽象类可以实例化。疑问解答:
1、抽象类中一定有抽象的方法?
答:不对的。抽象类中可以有抽象方法,也可以没有抽象方法。
2、有抽象方法的类,一定是抽象类?
答:对的。如果一个类中包含了至少一个抽象方法,那么该类必须是抽象类。
3、抽象类是否可以用final 修饰?
答:不可以,final 的类不能当父类,abstract的类只能当父类。互斥的。不能同时使用。
4、静态方法是否可以声明成抽象方法?
答:不可以,static 和 abstract 也是互斥的。
5、抽象方法是否可以使用 private 修饰?
答:不可以。私有的方法不能子类继承,不能继承就不能重写。 抽象方法就是为了让子类实现重写的。互斥的。
6、抽象类中定义的抽象方法,每一个抽象的方法都是定义了一个规则!!
答:每一个抽象方法,都是父类给实现的子类定义的一个规则:子类在实现父类抽象方法的时候,不管子类实现的细节如何,但是对实现的功能是有要求的。
7、抽象关键字不可以和那些关键字共存?
private => 非法的修饰符组合: abstract和private(抽象需要被覆盖)
static => 非法的修饰符组合: abstract和static
final => 非法的修饰符组合: abstract和final
8、抽象类和非抽象类的区别?
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) 局部内部类:定义在方法内部的,作用域只限于本方法,称为局部内部类。
局部内部类的的使用主要是用来解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类。局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法中被使用,出了该方法就会失效。局部内部类在实际开发中应用很少。
转载于:https://www.cnblogs.com/cao-yin/p/9029702.html
原文地址: https://blog.csdn.net/weixin_30376453/article/details/98634403
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章