目录
一、多态的补充
1、对象的转型
在我们使用多态的时候,子类是可以调用父类的方法或属性的,但是子类独有的,也就是不是从父类继承过来的方法和属性就调用不了,那这个时候我非要调用呢?怎么办呢?其实也是有解决办法的。看一个例子
package work726;
public class Animal {
public void eat(){
System.out.println("今天吃啥子,今天吃骨头");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("今天吃啥子,今天eat鱼肉");
}
public void catBark(){
System.out.println("你搞咩啊");
}
}
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("今天吃啥子,今天吃鱼香肉丝");
}
public void dogBark(){
System.out.println("你在狗叫什么啊");
}
}
现在再来创建一个测试类
package work726;
public class MainTest {
public static void main(String[] args) {
animalTest();
}
public static void animalTest(){
//创建一个Animal类型的Dog对象,体现了多态
Animal dogOne = new Dog();
Animal catOne = new Cat();
dogOne.eat();
// 调用父类有的方法,没有问题
// dogOne.dogBark();
// Animal类型的Dog对象调用不了Dog类独有的
// 不是从父类继承过来的方法,调用不了
// 同理
catOne.eat();
// catOne.catBark();
}
}
这时发现,Dog对象和Cat对象调用eat方法是没有任何问题的,怎么子类里面独有的方法用不了了呢,这是因为在实现多态的时候,系统自动把Dog对象和Cat对象转型了,自动转成Animal类型,而Animal类型的对象里面不包含子类的方法,当然调用不了啊。
现在再来看调用子类独有的方法
public class MainTest {
public static void main(String[] args) {
animalTest();
}
public static void animalTest(){
//创建一个Animal类型的Dog对象,体现了多态
Animal dogOne = new Dog();
Animal catOne = new Cat();
// dogOne.eat();
// 调用父类有的方法,没有问题
// dogOne.dogBark();
// Animal类型的Dog对象调用不了Dog类独有的
// 不是从父类继承过来的方法,调用不了
// 同理
// catOne.eat();
// catOne.catBark();
//把Dog类作为参数传入强转方法,并在强转方法内调用Dog类独有的方法
transformation(dogOne);
}
public static void transformation(Animal animal){
//传入Animal类型的Dog类对象,强转为Dog类型
Dog dog = (Dog)animal;
//这时就可以调用Dog类独有的方法了
dog.dogBark();
}
}
这时就可以调用了,使用多态的时候,系统自动给我转换了类型,那我再给它转回去就可以使用了啊,这是可以实现的。
2、instanceof关键字
instanceof关键字的作用就是用来判断某个对象是否是某个类的对象的,在什么时候需要使用它呢?,前面是我们指定传入一个Animal类型的Dog对象,之后把它强转成Dog类型的对象,那我们现在传入一个Animal类型的Cat对象呢?显然,这时不行的,程序报错,那我就是要在这个方法里面传入Cat对象呢?也是可以实现的,我们继续上面的例子
package work726;
public class MainTest {
public static void main(String[] args) {
animalTest();
}
public static void animalTest(){
//创建一个Animal类型的Dog对象,体现了多态
Animal dogOne = new Dog();
Animal catOne = new Cat();
// dogOne.eat();
// 调用父类有的方法,没有问题
// dogOne.dogBark();
// Animal类型的Dog对象调用不了Dog类独有的
// 不是从父类继承过来的方法,调用不了
// 同理
// catOne.eat();
// catOne.catBark();
//把Dog类作为参数传入强转方法,并在强转方法内调用Dog类独有的方法
transformation(dogOne);
transformation(catOne);
}
// public static void transformation(Animal animal){
// //传入Animal类型的Dog类对象,强转为Dog类型
// Dog dog = (Dog)animal;
// //这时就可以调用Dog类独有的方法了
// dog.dogBark();
// }
public static void transformation(Animal animal){
//判断传入的是什么对象
//传入的是Dog类对象就强转成Dog类
if(animal instanceof Dog){
Dog animal1 = (Dog) animal;
animal1.dogBark();
}
//传入的是Cat对象就强转成Cat对象
else if(animal instanceof Cat){
Cat animal1 = (Cat) animal;
animal1.catBark();
}
}
}
如上代码,这个时侯instanceof关键字的的作用就体现出来了,传入Animal类型的对象后,判断是否是Dog对象或者Cat对象,之后再进行强转,这样是没得问题的。
二、抽象类
1、什么是抽象类?
一个类被abstract关键字修饰,那么这个类就是一个抽象类。
抽象类可以含有或者不含有抽象方法,但一个抽象方法一定是属于一个抽象类的。
抽象是一个隐藏实现细节并只向用户显示功能的过程。
抽象类里的抽象方法不包含方法体,由继承该抽象类的子类具体实现。
抽象类必须由子类继承并实现,不然抽象类将毫无意义。
2、抽象类有什么用?
模板作用,抽象类是用来捕捉子类的通用特性的,是被用来创建继承层级里子类的模板。现实中有些父类中的方法确实没有必要写,因为各个子类中的这个方法肯定会有不同;而写成抽象类,这样看代码时,就知道这是抽象方法,而知道这个方法是在子类中实现的,所以有提示作用。
3、抽象类如何实现?
1、抽象类
定义格式:public abstract class 类名字 { }
2、抽象方法
定义格式:修饰符 abstract 返回值类型 方法名 (参数列表);
4、使用抽象类时需要注意的地方?
前面讲了,抽象类必须由子类继承,不然抽象类就毫无意义,还有抽象类里的所有抽象方法子类必须重写,不然也通不过编译除此之外还有几点:
1、抽象类不能创建对象
如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
2、抽象类中可以有构造器
抽象类的构造器是供子类创建对象时,初始化父类成员使用的。