💕"没有眼泪我们就会迷路,彻底变成石头,我们的心会变成冰凌,吻会变成冰块。"💕
作者:Mylvzi
文章主要内容:JavaSE学习之--抽象类,接口,内部类
一.抽象类
1.抽象类的定义
我们知道,对象是通过类来描绘的。但并不是所有的类都用来描绘对象,当你抽象出来的类所含有的信息不足以描绘出一个完整的对象时,这个类就叫做“抽象类”(所有的实现细节需要子类来自己完成)
我们发现shape中draw方法无法被具体实现,需要在对应的子类中实现,我们把这种方法叫做“抽象方法”,抽象方法就是所有子类方法的“蓝图”,根据这个蓝图来创建不同的子类特有的方法!同时,含有抽象方法的类就是抽象类!
2.抽象类的语法规则--abstract关键字
抽象类往往是父类,子类继承抽象类实现子类特有的方法,创建抽象类是通过关键字abstract
// abstract关键字创建抽象类 abstract class Shape { // 创建抽象方法 不需要具体执行过程 是一个蓝图 public abstract void draw(); }
3.抽象类的注意事项
1.抽象类无法实例化对象
抽象类包含的信息无法描绘一个完整的对象,所以无法通过抽象类来实例化对象!
Shape shape = new Shape();
2.抽象类中可以存在普通成员变量,普通成员方法
abstract class Shape { // 普通成员变量 int a; // 普通方法 public void method() { System.out.println("普通方法!"); } // 抽象方法--》不能含有函数体 abstract void method2(); } class Rect extends Shape { @Override public void method() { System.out.println("普通方法!"); } @Override void method2() { System.out.println("抽象方法!"); } }
3.抽象方法不能被private修饰
如果一个方法被private修饰,那他只能在此类中使用,也就是只能在抽象类中使用,而抽象类的方法就是用来被子类重写的,所以抽象类方法不能被private修饰
4.抽象方法不能被final和static修饰
如果一个方法被final修饰,则该方法无法被重写;如果被static修饰,那么此方法是属于类的,无法被重写 (要谨记,重写是子类对父类方法的重写,被static修饰的方法无法被继承或重写)
5.抽象类必须被继承,且子类必须重写抽象类所有的抽象方法(可以快捷键创建)
abstract class Shape { public abstract void draw(); public abstract void trangle(); } class Rect extends Shape { // 抽象方法必须被重写 @Override public void draw() { System.out.println("矩形"); } @Override public void trangle() { } } class Flower extends Shape { // trangle方法未被重写 // 只重写一个抽象方法-->err // 所有的抽象方法必须被重写! @Override public void draw() { System.out.println("✿"); } }
注意到,这个报错的前一句是“Flower不是抽象的”,那是不是说明子类的也可以是抽象类呢?答案是可以的,Java中允许抽象子类,抽象子类将继续把抽象方法传递给他的子类,让他的子类来重写该抽象方法,形成了类的层级结构(但是不推荐将子类设置为抽象类,因为要重写多个方法)
abstract class Shape { public abstract void draw(); public abstract void trangle(); } abstract class Flower extends Shape { // 只重写一个抽象方法-->err // 所有的抽象方法必须被重写! @Override public void draw() { System.out.println("✿"); } } class SmallFlower extends Flower { // 父类Flower的抽象类 @Override public void trangle() { } // shape的抽象类 @Override public void draw() { draw(); } }
6.抽象类可以存在构造方法,供子类初始化父类的成员变量(抽象类自己无法初始化)
abstract class Shape { // 父类的成员变量 int a; // 父类的构造方法 public Shape(int a) { this.a = a; } // 抽象方法--》不能含有函数体 abstract void method2(); } class Rect extends Shape { int b; public Rect(int a,int b) { super(a); this.b = b } @Override void method2() { System.out.println(a); } }
7.抽象类中不一定含有抽象方法,但抽象方法存在的类一定是抽象类!!!
抽象类存在的意义是什么?多一层编译检查!!!
抽象类中抽象方法的存在强制了子类必须重写抽象方法,如果你想让所有的子类都包含某种方法,但具体的行为还要取决于具体的子类,就可以在抽象类(父类)中将此方法设置为抽象方法!
普通类的方法可以被继承,重写,但普通类的方法是具体实现的,有可能通过子类误调用成父类的方法,而抽象类的抽象方法不是具体实现的,他是一个“模板”,不含有函数体,所有的子类都可以根据自身情况去重写该方法,且不会出现误调用的情况!
二.接口(interface)
1.接口的定义
接口常见于我们的生活之中,比如最经典的是一直被诟病的苹果接口,众所周知,苹果接口只能给苹果手机充电,适用范围仅限于苹果设备,无法通过type-c接口充电,也就是说只有符合苹果规范的设备才能使用苹果接口!苹果接口是所有苹果设备的“共同规范”!
计算机中的接口也是类似的,是一种“共同规范”,简而言之类似于“父类”,所有能使用此接口的类都符合接口设定的规范(也就是类含有接口中的方法!!!)
2.接口的语法
// 将class替换为interface public interface IShape { // 接口中的所有方法都默认是public abstract的 public abstract void method1(); void method2(); // 接口中的成员变量都是默认被public static final修饰的 }
1.接口关键字--》interface(替换原来的class),接口名一般以I开头(规范性)
2.关于接口方法
接口中的所有方法都默认是public abstract的,为了代码的规范性和简洁性,推荐第二种写法(method2)
3.接口的实现--implements关键字
我们创建了接口,接下来就要使用接口,相当于你把苹果手机插入到苹果接口,接下来就要使用苹果手机了;在Java中,我们称之为类实现接口
接口的实现是通过关键字--implements
public interface IShape { void drawMap(); } // implements关键字代表此类实现该接口 class Rect implements IShape { @Override public void drawMap() { System.out.println("矩形!!!"); } } class Flower implements IShape { @Override public void drawMap() { System.out.println("❀❀❀"); } } public class Testdemo { // 类似于类里面的向上转型!!! public static void drawMap2 (IShape ishape) { ishape.drawMap(); } public static void main(String[] args) { drawMap2(new Rect()); drawMap2(new Flower()); } }
注意事项:
1.子类与父类是继承关系,类与接口是实现关系,接口和父类很相似,很多用法都是类似的
2.接口中的方法都是抽象方法,实现接口的类必须重写接口中所有的方法!
3.接口中不能存在普通方法 !!!
4.一个例子
代码实现:
// USB接口 public interface IUSB { void openDevice(); void closeDevice(); } // 鼠标类 public class Mouse implements IUSB { // 实现USB接口就是重写USB接口中的所有方法 @Override public void openDevice() { System.out.println("鼠标设备开启!"); } @Override public void closeDevice() { System.out.println("鼠标设备关闭!"); } public void clickMouse() { System.out.println("鼠标点击"); } } // 键盘类 public class KeyBoard implements IUSB { // 实现USB类 @Override public void openDevice() { System.out.println("键盘设备开启!"); } @Override public void closeDevice() { System.out.println("键盘设备关闭!"); } public void inKeyBoard() { System.out.println("键盘输入!"); } } // 计算机开机--通过usb使用相关设备--关机 public class Computer { public void openComputer() { System.out.println("电脑开启!"); } public void closeComputer() { System.out.println("电脑关闭!"); } // 使用usb设备(类似于向上转型) public void useUSB(IUSB iusb) { // 注意这里开启,关闭设备是Mouse和KeyBoard类共有的,写在外面即可 iusb.openDevice(); // 利用关键字instanceof来判断引用的是哪个类 if (iusb instanceof Mouse) { ((Mouse) iusb).clickMouse(); //clickMouse是Mouse特有的方法,无法直接通过iusb实现 /* Mouse mouse = (Mouse) iusb; mouse.clickMouse();*/ }else if(iusb instanceof KeyBoard) { ((KeyBoard) iusb).inKeyBoard(); } iusb.closeDevice(); } } // 测试类 public class Testdemo3 { public static void main(String[] args) { Computer computer = new Computer(); computer.openComputer(); // 设备使用 computer.useUSB(new Mouse()); computer.useUSB(new KeyBoard()); computer.closeComputer(); } }
3.接口的特性
1.接口类型是一种引用类型,但是不能直接new接口对象(类似于抽象类)
interface IUSB { } public class Test1 { public static void main(String[] args) { IUSB iusb = new IUSB(); // err }
2.接口的方法默认都是被public abstract修饰的,使用其他修饰符会报错
interface IUSB { void method1(); public abstract void method2(); private void method3(); }
3.接口中的方法都不带有主体,只能有实现接口的类来实现
interface IUSB { void method1() { System.out.println("hehe"); } }
4.重写接口的抽象方法时,不能使用默认权限,只能是public修饰
接口中的方法默认都是public权限的,实现接口的类中重写的方法的权限不能比Public低,所以只能是Public修饰的
interface IUSB { // 默认是public abstract void method(); } class Mouse implements IUSB { @Override // err // 接口中的方法都是public权限 void method() { System.out.println("hehe"); } }
5.接口中可以有变量,但变量都是被public static final修饰的
static:说明变量是属于类的,能直接通过类来访问
final:证明变量无法被修改
interface IUSB { int a = 10; } public static void main(String[] args) { System.out.println(IUSB.a);// 可以直接通过接口访问-->被static修饰 IUSB.a = 20;// err无法被修改 }
6.接口中不能有构造方法和代码块
public interface INTERFACE { // err { } // err static { } }
7.接口编译完成的字节码文件的后缀格式也是.class
JavaSE学习之--抽象类,接口,内部类(二)+https://developer.aliyun.com/article/1413499