对象类型转换
1. 向上转型
举个例子:比如你可以说鹰是一个禽类,禽类又是一个动物类,也可以说鹰是一个动物,但是不能说动物就是一个鹰吧,
这里有一个动物类
class Animal {………};
一个鹰继承动物类
class Eagle extendsAnimal {……}
在实例化的时候,你可以这样做
Animal eagle = new Eagle();//因为鹰类本来就是继承的动物类,所以可以说鹰就是动物
向上转型的优点:由于向上转型是从一个比较具体的类到一个比较抽象的类的转换,所以它总是安全的。比如,可以说鹰永远都是禽类或者动物,但不能说动物就是鹰
2. 向下转型
还是上面那个例子,通过上面的例子可以推出向下转型是将抽象类转换成具体的类型,但是这种转型通常会出现问题,接下来就要展示一下如何处理这种问题
public static void main(String args[]){
Animal eagle =new Eagle();
//Eagle e =eagle;直接将父类对象给子类对象是错误的。
Eagle e = (Animal)eagle;//将对象强转成父类对象。这种做法才是正确的。
我们可以看到,如果将父类对象直接给子类,会发生编译错误,因为父类对象不一定是子类的实例,还是这个解释:可以说鹰永远都是禽类或者动物,但不能说动物就是鹰,也可能是兔子,是马。越是具体的对象,特性越多,越是抽象的问题,特性越少,将特性范围小的对象赋值给特性范围大的肯定会出现问题。
有人会说你这不是没用的代码吗?把它变成另一个又转换回来。别急来看下一个知识点你就会明白它的用途了。
3. 使用instanceof操作符俩进行判断对象类型
当执行向下转型的操作的时候,如果父类对象不是子类对象的实例,那么就会出现问题,会抛出ClassCastException异常,所以在进行向下转型操作的时候要养成判断父类对象是否是子类对象实例的习惯
下面引入一下应用场景
当我们在玩多态的时候,往往在参数中传入的都是父类类型的引用。
有一个方法
public void A(Animal e){
if(e instaceof Eagle){
Eagle e= (Animal)eagle;
……….
}
………………………….
}
那么通过这个方法是不是也已经知道了它的用法了呢?它的用法就是
实例 instaceof 类型名
这样就可以判断父类引用是不是子类的类型!如果是在进行强转,这样的话就安全了很多
抽象类和接口
抽象类
1. 抽象类是什么?
所谓抽象类就是就是一个用abstract定义的类型,这个类型中可以有abstract关键字修饰的方法,这个方法就是抽象方法,抽象方法没有方法体。这个方法本身没有任何意义。这个方法只能被重写。继承抽象类的普通类必须重写此抽象方法
2. 抽象类的一般格式
public abstract class 类名{
abstract void test();//定义抽象方法
voidtest2();//定义普通方法
}
3. 抽象类的一些要求
1)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
2)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);
3) 抽象类不能使final修饰,因为抽象类是必须被继承的,而final是最终的,不能被继承的这与abstract相矛盾,
4)抽象方法不能用static,final,native,private并列修饰同一个方法(因为这几个关键字都与abstract是矛盾的,不能共存的,会报错的),只能是public或者protectedabstract来修饰这个抽象方法
5)抽象类不能实例化,但是有构造器
4.为什么使用抽象类,抽象类的意义
有人会问抽象类这么多规矩,为什么要使用抽象类呢?我自己的理解是为了以后修改代码方便和玩多态的时候更加的灵活
抽象类就相当于一个框架一个模板,比如说,上帝定义了人类长了一张嘴,两个眼睛,一个鼻子,两个耳朵。而至于具体每个人长成什么样,,帅还是丑,那得看他自己了,这个时候所有的具体的人都可以被称为一个人。也就是抽象类。具体的人是继承抽象类的子类的一个实例。
说了那么多那么优势到底在哪里?举一个例子,在我们的代码里面可以通过向上转型把把子类的对象转换成父类的对象,。Animale = new Eagle();然后e.eat();e.drink(),
e.jump(),………写了很多方法,然后突然,客户改了逻辑不是Eagle做这些事了,而是Goose做这些事,这个时候只要让Goose也实现Animal,然后Animal e = new Goose();是不是其他代码e.eat();e.drink(),e.jump(),………,都不用修改了,就变成Goose去做这些事了,这就是抽象类的好处。这就降低了程序的耦合度,提高了代码的可维护性。
5. 抽象类的不足与接口的引入。
继承抽象类的子类需要将抽象类的所有抽象方法实现,而子类有时候可能并不需要这个抽象方法,有的类却需要,这个时候怎么办呢?我们是否可以在抽象类中只定义大家都需要的方法,而每个类需要的不同的方法可以通过继承另外的抽象类来实现呢,答案是不可以的,因为java是单继承的,那怎么办,于是接口的就被定义出来了,专门用来补充一部分功能,也可以来代替抽象类。
接口
1. 什么是接口:
接口可以认为是特殊的抽象类,那么到底是特殊在哪里呢?接下来请仔细看。
1) 接口中的方法都是抽象方法,2)接口中的变量都是public static final修饰的
2) j接口用interface来定义,用implements来实现
2. 接口的语法
Public interface drawTest{
Int a=10;//省略了public static final
void draw();//接口中的方法省略了abstract
}
3. 接口的一些注意的地方
1.)接口用interface定义
2)接口中的方法是省略abstract的,变量是省略public static final
3)接口中的所有方法都是抽象的方法。
4)接口用关键字implements来实现
5)可以实现多个接口。用 implements A,B,,C..这样做
6.)接口是没有构造器的,也不能实例化,这一点要与抽象类区分。抽象类是有构造器,但是不能实例化
7)接口也可以向上转型和抽象类一样
8)接口也可以继承另外的普通类,或者实现一个接口
8.)其他和抽象类一样