戚权20200929
知识点
1.多态
1.1多态
一个特定类型的变量,可以引用多个不同类型的对象,并且能自动调用引用对象的方法。也就是
说根据引用对象的不同,响应不同的操作。
-
多态是面型对象的三大特征之一
-
方法重写是实现多态的基础
多态以为这在一次方法调用中根据包含的对象的实际类型(即实际子类的对象)来决定应该调用哪个子类的方法,而不是由用来储存对象引用的变量的类型决定的。
public class Pet {
public void toHospital() {
System.out.println("宠物看病");
}
}
class Dog extends Pet{
public void toHospital() {
System.out.println("狗狗看病");
}
}class Cat extends Pet{
public void toHospital() {
System.out.println("猫猫看病");
}
}
public static void main(String[] args) {
Dog dog = new Dog() ;
dog.toHospital();//狗狗看病
Cat cat = new Cat();
cat.toHospital(); //猫猫看病
System.out.println("=================");
//多态
Pet pet;
pet = new Dog();
pet.toHospital();//狗狗看病
pet = new Cat();
pet.toHospital(); //猫猫看病 }
//pet是Pet类型的,但是其中存储的是Dog()的对象的引用,在调用方法时在看他引用的对象不是看他是哪个类型。
多态中,变量引用的是哪个对象,就执行的是哪个对象中相对应的方法。
1.2向上转型
由子类类型转换成父类类型,称为向上转型。父类引用指向子类对象
//父类类型 变量 = 子类类型实例;
Pet pet = new Dog();//向上转型
多态就是说一个父类可能有多个子类,每个子类都重写了父类的方法(每个子类都有不同的方法实现),当父类调用方法时,父类引用指向的是哪个子类,就执行哪个子类的方法。形成了父类引用调用相同的方法时,有不同的实现。
-
父类引用只能调用子类从父类继承的方法或重写的方法
-
父类引用不能调用子类扩展的方法(独有的方法)
1.3实现多态的三个条件
-
子类继承父类,并且子类重写父类的方法
-
父类引用指向子类对象(父类引用可以指向任意一个子类的对象)
-
父类引用调用方法时,实际上调用的是子类的方法(父类指向那个子类就调用哪个子类的方法),不同的子类有不同的方法实现,体现出同一个方法在不同子类中的不同形态的表现。
1.4向下转型
由父类类型转换成子类类型,称为向下转型。必须要进行强制类型转换。
-
注意:首先要判断是否属于要强转的类型( instanceof ),如果不属于会报java.lang.ClassCastException
-
当向上转型发生后,将无法调用子类新增的方法。但是如果需要调用子类新增的方法,可以通过把父类转换为子类实现。
public static void main(String[] args) {
// Dog dog = (Dog) new Pet();//向下转型 java.lang.ClassCastException
// System.out.println(new Pet() instanceof Dog); // false
Pet pet = new Dog(); //向上转型
Dog dog = null;
if(pet instanceof Dog){
dog = (Dog) pet; //向下转型
}
System.out.println(pet.getClass()); //class com.itlaobing.demo.Dog
System.out.println(pet instanceof Dog); //true
}
1.5instance运算符
-
instance of通常和强制类型转换结合使用
-
使用instanceof时,对象的类型不许和instanceof后面的参数所指定的类有继承关系,否则会出现编译错误。
1.6多态的应用
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
- 详细见书p146
1.7以父类类型作为方法的参数
父类类型出现的地方,子类都可以出现(使用)。
public void toHost(Pet pet) {
System.out.print("主人带");
pet.toHospital();
}
public static void main(String[] args) {
Person person = new Person();
Dog dog = new Dog();
person.toHost(dog);
Cat cat = new Cat();
person.toHost(cat);
Pet pet = new Pet();
person.toHost(pet);
}
1.8使用父类类型作为方法的返回值
public Pet getPet(int type) {
if(1 == type) {
return new Dog();
}else if(2 == type) {
return new Cat();
}else {
return new Pet();
}
}
1.9多态的使用
- 接口
- 重写
- 抽象类方法
1.10 static
方法的多态
public static void main(String[] args) {
Pet p = new Dog();
p.getInstance(); // Dog getInstance()
p.staticMethod();// Pet staticMethod()
}
- p.getInstance() 调用的是 Dog 类中的方法,因为在 Dog 类中重写了 Pet 中的 getInstance()方法,且调用实例方法看的是哪个对象调用就执行哪个对象中的方法。也就是说 by Class 。
- p.staticMethod() 调用的是 Pet 类中的方法,因为 staticMethod() 是 static 方法,属于类。虽然 Dog 类中隐藏了父类的方法,但是调用 static 方法看的是类型,也就是说 by type 。
- 可以简单的说,调用 static 方法看左边。调用 实例方法 看右边。
2.抽象类与抽象方法
2.1抽象类
在 java 中,被 abstract 关键字修饰的类叫做抽象类,被 abstract 关键字修饰的方法叫做抽象方法。抽象方法是没有具体实现(没有方法体)的。 abstract 不能和 final 一起使用。
抽象类/抽象方法作用就是定义规范
2.2抽象方法和普通方法的区别
[修饰符] 返回值类型 方法名([参数列表]){ //普通方法
//方法体
}
[修饰符] abstract 返回值类型 方法名([参数列表]); //抽象方法
- ##### 抽象方法和抽象类
//抽象类
public abstract class Pet {
//抽象方法
public abstract void toHospital();
}
-
我们看到,抽象方法没有具体的实现(没有方法体),所以,抽象不能执行。
-
抽象方法是由继承了抽象类的子类重写后调用子类重写的方法来执行。
-
区别:
- 抽象方法有 abstract 修饰,
- 抽象方法没有方法体,
- 抽象方法无法执行,
- 抽象方法不能用 private 修饰
2.3 抽象类和普通类的区别
[修饰符] abstract class 类名{} //抽象类
[修饰符] class 类名{} //普通类
- 抽象类中可以有普通方法
- 如果一个类继承了抽象类,那么这个类必须重写它的抽象方法,或者将类声明为抽象类
- 抽象类是有构造方法的,但是不能被实例化。
- 构造方法、类方法( static )不能声明为抽象( abstract )方法
区别
- 抽象类有 abstract 修饰,
- 抽象类中可以有抽象方法,
- 抽象类不能被实例化,需要抽象类变量引用其子类的对象
抽象类除了不能被实例化以外,和普通了类没有区别。定义抽象类是为了强迫子类实现抽象方法,是定义规范的
一个类中只要含有抽象方法,这个类就必须是抽象类;抽象类不一定含有抽象方法
2.4本质
上层代码定义规范,不用实现。具体业务实现由子类完成,调用者不用关心。
3.接口
3.1接口
- 约定好规范,然后按照规范来做。接口就是定义规范。
- java 中的接口作用和生活中类似,它提供一种约定,使实现接口的类在形式上保持一致。
- 抽象类中可以有普通方法而接口中的方法都是抽象的,也可以说接口是一个特殊的 抽象类 ,接口不能被实例化,而且没有构造方法。
3.2定义接口
[修饰符] interface 接口名{
//接口成员
}
public interface USBInterface {
public static final String NAME = "";//静态常量
public void service();
}
- 接口中的方法默认是抽象方法,所以可以省略 abstract 修饰符
- 接口中的方法默认都是 public 的,所以可以省略 public
- 接口中的变量只能是静态常量( static final ),所以可以省略 static final ,静态常量在定义时就要赋值,且不可变。
3.3使用接口
接口使用和抽象类一样,都是通过子类。子类通过 implements 关键字实现接口,实现接口就必须实现接口中的抽象方法
public class USBDisk implements USBInterface{
@Override
public void service() {
System.out.println("service()");
}
}
- 一个类可以实现多个接口,接口之间使用 , 隔开
- 接口的实现类中,可以有普通方法
- 实现的方法必须是 public 的
3.4实现多个接口
java 中继承是单继承,使用 extends 关键字;但是一个类可以实现多个接口,使用 implements ,多个接口之间用 , 隔开。
public class Computer implements USBInterface, ChargeInterface{
public void play() {
System.out.println("play game");
}
@Override
public void charge() {
System.out.println("充电"); }
@Override
public void service() {
System.out.println("USB接口");
}
}
一个类可以同时继承和省实现接口,extent要在implement之前
public class LenovoComputer extends Computer implements USBInterface, ChargeInterface{
}
接口与接口之间是继承关系,使用 extends 关键字。多个接口使用 , 隔开
public interface USBC extends USBInterface,ChargeInterface{
}
3.5jdk接口新特性
在 jdk8.0 中 default 关键字可用于在接口中修饰方法(默认方法), default 修饰的方法可以有具体实现,也只能在接口中出现。 default 修饰的方法可以被重写。
public interface USBInterface {
public static final String NAME = "";
void service();
public default void test() {
service();
System.out.println("service test");
}
}
public class UDBDisk implements USBInterface{
@Override
public void service() {
System.out.println("service()");
}
@Override
public void test() {
}
public static void main(String[] args) {
USBInterface u = new UDBDisk(); u.test();
}
}
接口中还可以有 static 修饰的方法,称为静态方法(类方法)。类方法可以直接使用接口名.方法名调用。
public interface USBInterface {
public static void test1() {
System.out.println("test1");
}
}
总结
今天学习了知识点特别多,多态,抽象,接口,内部类,这些知识点也特别的多。今天大致记忆了一些,还没有记忆完的。然后明天继续加油。
评论留言