前言:继承只是个开始,要使用多态还需要接口.接口是100%纯抽象的类.抽象类是无法初始化的类
Animal anim=new Animal();
初始化animal显得很奇怪,换句话说animal不应该被初始化,你只应该初始化老虎,狮子等具体动物,不能被初始化可以通过标记类为抽象类(abstract),实现该类不能创建如何类型的实例,但是还可以用这种抽象的类型作为引用变量类型
如Animal aHippo=new Hippo();
具体的类是可以被初始化为对象的,抽象类则不可以,抽象类的关键词abstract
除了类可以被标为抽象类,方法也可以成为抽象方法,抽象的方法代表该方法一定被覆盖过
抽象方法(由于没有通用的处理方法)没有实体,声明以;结束.编写抽象方法的程序代码无意义,如
public abstract void eat();
声明了抽象方法的类也必须标记为抽象类
你必须实现所有的抽象方法,类比于覆盖方法,意味着在继承树结构下得第一个具体类必须要实现所有的抽象方法,必须以相同的方法名称和参数及相容的返回类型创建出非抽象方法,但还是可以通过抽象机制将实现的负担转给下层,如将animal与cannie标记为抽象类,让具体类Dog来实现抽象方法.
多态的使用
抽象类可以带有抽象方法和非抽象方法.
ArrayList通过对象这个类型来操作所有类型的对象
JAVA中所有的类都是从object这个类继承出来的,即它是所有类的父类,代表所有类直接或间接继承object类
关于产生对象的哈希代码与运用哈希表上的对象以后讨论.
类对象
部分方法:
boolean
equals()
Class getClass()
int hashCode() //列出对象的哈希代码
String toString() //列出类的名称和一数字序列
Tips:
1.Object类是具体的,类比于animal,对此类初始化合理性在于适用需要通用的对象的场景,最常见的用途在于线程的同步化
2.Object类有以下目的:
1)作为多态让方法应付多种类型的机制
2)提供JAVA在执行期间对任何对象都有需要的方法的实现程序代码,如equals()
3.当某个对象以object类型来引用时,JAVA会把其当做object实例,意味着只能调用object类所声明的方法,例如
Object o=new Ferrai();
o.goFast();//非法
使用object类型的多态引用是会付出代价的
例如
ArrayList<Object> myDog=new ArrayList<Object>();
Dog aDog=new Dog();
myDog.add(aDog);
Dog d=myDog.get(0);//illegal
调用get()方法会返回object类型,编译器无法确认它是Dog
任何从ArrayList<Object>取出的东西都会被当作object类的实例而不管原来是什么,所以从中取出的变量只能被object引用,对于上例,取得了Dog实例的Object引用.
Dog --->ArrayList<Object>--->object
Football--->ArrayList<Object>--->object
Fish --->ArrayList<Object>--->object
同理,观察以下的程序
public void go(){
Dog aDog=new Dog();
Dog sameDog=getObject(aDog); //error
Object sameDog1=getObject(aDog);//right,可以赋值任何东西给Object类型的引用变量
aDog.bark(); //right
sameDog1.bark(); //error:object不知道什么是bark()
}
public Object getObject(Object o){
return o; //返回同一个对象,但类型已经转变为Object了
}
编译器是根据引用类型来判断哪些方法可以调用而不是根据object的确实类型
object类是所有类的父类,所以每个对象除了真正的类型外还可以当作object处理,即创建对象时堆上不仅有特定的对象外,此特定对象还包含一个object在里面
转换为原来的类型
对于这种Dog实例的Object引用,可通过从object中拷贝出一个Dog引用,并赋值给Dog引用变量,即
Object o=al.get(index);
Dog d=(Dog) o;//实现类型转换
d.roam;
可通过如下代码检测object的确实类型
if(o instanceof Dog){
Dog d=(Dog) o;
}
总结:你只有在引用变量的类确实有该方法时才能调用它
接口可以解决多重继承的问题但又不会产生致命方块
JAVA只有单继承,但一个类可以实现多个接口
Java的接口是100%的纯抽象类即所有接口的方法是抽象的.
比如所有pet的类(包括子类)都必须要实现这些方法
接口的定义
public interface pet{ interface取代class
public abstract void play();
//修饰符只是强调作用
public abstract void fight);//方法一定是抽象的
}
接口的实现
public class Dog extends Canie implements Pet{}
打算将对象的形态保存在文件中,只要去实现serializable接口就行.
当你把一个类当作多态类型应用时,相同的类型必须来自同一个继承树,且必须是该多态类型的子类,定义为canine类型的参数可以接受wolf和dog,但无法接受cat
但当用接口作为多态类型时,对象可以来自任何地方,唯一的要求是该对象必须是来自实现此接口的类.
若以接口取代具体的子类或抽象的父类作为参数或返回类型,则可以传入任何有实现该接口的东西.即使用接口可以继承超过一个以上的的来源.
super关键字引用父类的对象,可调用父类的方法
总结:
1.object类的对象在没有类型转换时不能赋值给其他类型
2.定义子类的模板,又不想让程序初始化模板-->抽象类
需要某类的特殊化模板,覆盖或增加新的方法-->子类
定义出类可以扮演的角色--->接口
3.方法可以声明object的参数或返回类型