javase增强02
作者:互联网
抽象类和抽象方法
/**
抽象类
*/
abstract class Animal{
/**
抽象方法
*/
public abstract void eat();
}
使用abstract修饰,抽象方法只有方法签名,没有方法体
一个类中定义了抽象方法,那么这个类一定是抽象类
如果一个类继承自抽象类,那么必须完成父类的所有抽象方法,否则这个类也必须定义成抽象类
普通类的元素抽象类都具有
抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
抽象类不能创建对象
抽象类失去了创建对象的资格,为什么?(反正法,假如可以创建对象)、
final和abstract是什么关系?
- 互斥关系
- abstract定义的类一定要被继承,final修饰的类不可以被继承
- abstract修饰的方法要被重写,final修饰的方法不可以被重写
模板方法模式
如果两个类中的方法,具有相同的部分,那么把不相同的部分替代成抽象方法,让子类继承抽象类,实现该抽象方法
模板方法建议使用final进行修饰,防止子类重写,造成模板方法失效
模板方法定义了方法的通用结构,将不能确定的部分定义成抽象方法,交给子类去实现,只关心自己需要实现的
public abstract class People {
/**
模板方法
*/
public final void introduce(){
System.out.println("你好");
// 将不确定的地方定义成抽象类
oneself();
System.out.println("谢谢收听");
}
/**
抽象类,子类实现
*/
public abstract void oneself();
}
接口
public interface 接口名{
// 常量 public static final
// 抽象方法 public abstract
}
-
什么是接口
接口是一种规范,规范是公开的,变量默认是public static final修饰,方法默认public abstractinterface School{ // 常量 public static final String name = "辽工大" ; int age = 19; public abstract void getStudent(); void getTeacher(); }
-
接口是需要被类实现(implement)
class A implement 接口1,接口2{ }
- 接口可以被类单实现,也可以被类多实现
- 一个类实现接口,必须实现该接口所有抽象方法,否则这个类需要定义成抽象类
-
基本小结
- 类与类:单继承
- 类与接口:多实现
- 接口与接口:多继承
JDK8新增接口方法
-
默认方法:default修饰,对象调用
-
静态方法:static修饰,接口的静态方法,只能使用接口名进行调用
-
私有方法:private修饰,本类中使用
-
它们默认是public修饰
-
注意事项
多态
同类型的对象,执行相同行为时,会表现出不同的行为特征
(上转型对象)父类类型 对象名 = new 子类构造器()
-
多态中成员访问特点
- 方法调用:编译看左边,运行看右边
- 变量调用:编译看左边,运行也看左边(多态侧重行为多态)
-
多态的前提
有继承/实现关系;有父类引用指向子类对象,有方法重写 -
多态的优势
-
在多态的形势下,右边对象可以实现解耦合,便于扩展和维护
animal a = new Dog(); a.run;// 后续行为随对象而变,后续代码无需修改
-
定义方法的时候,使用父类型作为参数,该参数可以接收一切子类对象,体现对台的扩展性与便利
-
-
问题
多态下不能使用子类独有的功能
(可以使用强制类型转换,可以解决多态下的劣势)
-
引用类型的类型转换
-
自动类型转换(从子到父):子类对象赋值给父类类型的变量指向
-
强制类型转换(从父到子):
-
子类类型 对象名 = (子类类型)父类类型的变量
-
作用:可以解决多态下的劣势,可以实现调用子类独有的功能
-
注意:如果强制转型后的类型和当前对象真实类型不是同一种类型,那么编译可以通过,但是运行会报异常
Animal t = new Cat(); Dog d = (Dog)t;//编译不会报错,程序运行会出现异常ClassCastException
java建议强制转型前使用instanceof判断当前对象的真实类型,再进行强制转换
// 使用 instanceof判断类型 if(a instanceof Dog){ Dog d2 = (Dog) a; }
-
-
内部类
定义在类中的类
-
静态内部类(不是重点)
public class Outer{ public class Inner{ } }
调用
Outer.Inner in = new Outer.Inner();
public class Outer { static String a="a"; String b = "b"; /** 学习静态内部类 */ public static class Inner{ /** 自定义方法 */ public void gerA(){ // 内部类可以直接调用外部类的静态成员 System.out.println(a); // 内部类不能直接访问外部类的实例成员 // System.out.println(b); Outer outer = new Outer(); System.out.println(outer.b); } private String name; public Inner() { } public Inner(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
-
成员(实例)内部类 (不重要)
- 无static修饰,属于外部类对象
- jdk16之前,成员内部类不允许定义静态成员,之后可以
public class Outer{ public class Inner{ } }
-
成员内部类创建对象格式
Outer.Inner in = new Outer().new Inner()
在成员内部类中,访问所在外部类对象,使用 类名.this
-
匿名内部类(重要)
本质上是一个没有名字的局部内部类,定义在方法,代码块中
作用:方便创建子类对象,最终目的为了简化代码编写
匿名内部类可以整体作为方法的实参传入
匿名类:
// 一般使用形式 Animal animal = new Tiger(); animal.run();
// 匿名内部类使用形式 Animal animal1 = new Animal() { @Override public void run() { } }; animal1.run();
-
匿名内部类本质上是一个没有名字的局部内部类
-
匿名内部类写出来就会产生一个匿名内部类的对象
-
匿名内部类的对象类型相当于当前new的这个类型的子类类型
-
匿名内部类也会产生class文件
-
标签:02,增强,子类,abstract,接口,public,javase,方法,抽象类 来源: https://www.cnblogs.com/WT404/p/16482202.html