博主:命运之光 专栏:Java零基础入门
学习目标 1.了解什么是抽象类,什么是接口; 2.掌握抽象类和接口的定义方法; 3.理解接口和抽象类的使用场景; 4.掌握多态的含义和用法; 5.掌握内部类的定义方法和使用方法;
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。
[修饰符] abstract class 类名 {
【修饰符】 abstract 返回值类型 方法名(【参数列表】); //抽象方法 ………..
}
🍓🍓抽象类的定义举例
abstract class A { // 定义一个抽象类,使用abstract声明
public void fun() { // 普通方法
System.out.println(“存在有方法体的普通方法!");
}
// 此方法并没有方法体的声明,并且存在有abstract关键字,表示抽象方法
public abstract void print();
}
抽象类定义好,但是如果要想使用抽象类则必须遵守如下原则:
①抽象类必须有子类,即:每一个抽象类一定要被子类所继承(使用extends关键字),但是在Java中每一个子类只能够继承一个抽象类,所以具备有单继承局限;
②抽象类的子类(子类不是抽象类)必须覆写抽象类之中的全部抽象方法(强制子类覆写);
③可以通过抽象类的子类完成抽象类的实例化对象操作。
把那些共有的、但不能具体实现的行为抽出来,定义成抽象的方法,作用有两点:
①抽象类可以包含抽象方法,也可以不包含抽象方法。但是包含抽象方法的类必须定义成抽象类;
②抽象类不能被实例化,抽象类可以被继承,所以不允许被定义成final类;
③抽象类中一定有构造器,便于子类实例化时调用。
④抽象方法只有方法的声明,没有方法体;
⑤继承抽象类的类必须实现抽象类的所有抽象方法,否则,也必须定义成抽象类;
⑥若子类重写了父类中的所有抽象方法后,此子类才可以实例化。
向上转型: 是指把一个子类的对象转成一个父类的对象。
语法格式:父类名称 对象名 = new 子类名称();
右侧创建一个子类对象,把它当作父类来看待使用。
注意:向上转型一定是安全的,没有问题的,但是也存在弊端。一旦向上转型为父类,那么就无法调用子类原本的独有方法。
向下转型是把一个父类对象转到一个子类对象(还原)。
语法格式:子类型名称 对象名 =(子类名称)父类对象;
将父类对象,(还原)成为本来的子类对象
注意:向下转型需要强制烈性转换,不一定安全,不推荐使用,除非明确知道被转换对象的实际类型是什么,能够确保转换正确才行。
日常生活中,两个实体之间进行连接的部分称为接口。如电脑和U盘连接的标准USB接口。接口可以确保不同实体之间的顺利连接。如不同厂家和U盘厂家只要按照相同的USB接口进行生产,那么所有的电脑和U盘就可以顺利的连接起来。
🍓🍓所谓的接口严格来讲就属于一个特殊的类,而且这个类里面只有抽象方法与静态常量(JDK1.8之前版本的定义)。
接口的定义格式为:
[public] interface 接口名 {
static final 类型名 常量名; //常量列表
public abstract 类型名 方法名(【参数列表】); //抽象方法列表
}
接口的定义跟类相似,只能定义成public权限或者默认权限。接口里的变量和方法都是公有的,即只能是public权限,但public可以省略。
接口使用规则
由于接口中存在抽象方法,所有接口对象不可能直接使用关键字new进行实例化操作。
格式如下:
[ 类修饰符] class 类名 [ extends 父类名 ] [ implements 接口名列表 ] {
成员变量定义;
成员方法定义;
}
🍓🍓例1:类实现多个接口。
interface A { // 定义接口
public static final String MSG = "MDIT"; // 全局常量
public abstract void print(); // 抽象方法
}
interface B { // 定义接口
public abstract void get();// 抽象方法
}
class X implements A, B { // X类实现了A和B两个接口
public void print() { // 覆写A接口的抽象方法
System.out.println("A接口的抽象方法!");
}
public void get() { // 覆写B接口的抽象方法
System.out.println("B接口的抽象方法!"); }
}
public class text1 {
public static void main(String args[]) {
// 此时X类是A和B两个接口的子类
X x = new X(); // 实例化子类对象
x.print();// 调用被覆写过的方法
x.get();// 调用被覆写过的方法
System.out.println(A.MSG);// 直接访问全局常量
}
}
🍓🍓例2:子类继承抽象类同时实现接口。
interface A { // 定义接口
public abstract void print(); // 抽象方法
}
interface B { // 定义接口
public abstract void get(); // 定义抽象方法
}
abstract class C { // 定义抽象类
public abstract void change(); // 定义抽象方法
}
class X extends C implements A, B { // X类继承了抽象类C,实现了A和B两个接口
public void print() { // 覆写接口A中的方法
System.out.println("A接口的抽象方法!");
}
public void get() { // 覆写接口B中的方法
System.out.println("B接口的抽象方法!");
}
public void change() { // 覆写抽象类C的方法
System.out.println("C类的抽象方法!");
}
}
public class text1 {
public static void main(String args[]) {
// 此时X类是A和B两个接口的子类
X x = new X(); // 实例化子类对象
x.print();// 调用被覆写过的方法
x.get();// 调用被覆写过的方法
}
}
🍓🍓接口的多继承。
一个类只能继承另外一个类,但一个接口可以同时继承多个接口,多个接口之间用英文逗号分隔开。
interface A { // 定义父接口
public void funA();
}
interface B { // 定义父接口
public void funB();
}
interface C extends A, B { // 利用extends,实现接口多继承
public void funC();
}
class X implements C { // 实现C接口子类要覆写全部抽象方法
public void funA() {
System.out.println("funa");
} // A接口定义的方法
public void funB() {
System.out.println("funb");
} // B接口定义的方法
public void funC() {
System.out.println("func");
} // C接口定义的方法
}
public class text1 {
public static void main(String args[]) {
// 此时X类是A和B两个接口的子类
X x = new X(); // 实例化子类对象
x.funA();// 调用被覆写过的方法
x.funB();// 调用被覆写过的方法
x.funC();// 调用被覆写过的方法
}
}
接口使用时需要注意: