多态
在同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态。继承是多态得以实现的基础
在Java中,为了实现多态,允许使用一个父类类型的变量来引用一个字类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。
interface Anmal{
void show(); //抽象类,抽象方法
}
class Cat implements Anmal{
@Override
public void show() { //实现抽象方法
System.out.println("我是一只猫,喵喵喵喵");
}
}
class Dog implements Anmal{
@Override
public void show() {
System.out.println("我是一只狗,旺旺旺旺");
}
}
public class Example01 {
public static void main(String[] args) {
Anmal cat = new Cat(); //创建Cat对象
Anmal dog = new Dog(); //创建Dog对象
animalshow(cat);
animalshow(dog);
}
//定义静态的animalshow方法,接收一个Animal类型的参数
public static void animalshow(Anmal an) {
an.show();
}
}
多态不仅解决了方法同名的问题,而且还使程序变得更加灵活,从而有效地提高了程序的可扩展性和可维护性
对象的类型转换
在多态的学习中,涉及到将子类对象当做父类类型使用的事情,此钟情况在Java的语言环境中称为"向上转型",例如以下两行代码
Animal an1 = new Cat(); //将Cat对象当做Animal类型来使用
Animal an2 = new Dog(); //将Dog对象当做Animal类型来使用
将子类对象当做父类使用时不需要任何显式的声明,需要注意的是,此时不能通过父类变量去调用子类中的特有方法
将父类类型的变量强制转为子类类型
public static void animalshow(){
Cat cat = (Cat) animal; //将animal对象强制转换为Cat类型
cat.show() //调用cat的show()方法
cat.sleep() //调用cat 的sleep()方法
}
这种父类型当做子类型使用的情况,在Java的语言环境中被称为"向下转型"。
Java提供一个instanceof关键字,它可以判断一个对象是否为某个类(或接口)的实例或者子类实例,语法格式如下:
对象(或者对象引用变量) instanceof 类(接口)
示例:
public static void animal(Animal animal){
if(animal instanceof Cat ){ //判断animal是否是Cat类的实例对象
Cat cat = (Cat) animal; //animal强转为Cat类型
cat.sleep(); //调用Cat的sleep()方法
cat.show(); //调用Cat的show()方法
}else{
System.out.println("this animal is not a cat");
}
使用instanceof关键字判断animalshow()方法中传入的对象是否为Cat类型,如果是Cat类型就进行强制类型转换,否则就打印"this animal is not a cat"
Object类
在JDK中提供了一个Object类,它是类层次结果的根类,每个类都直接或间接继承自该类。所有对象(包括数组)都实现了这个类的方法
equals() 指示其他某个对象是否与此对象"相等"
getClass() 返回此Object的运行时类
hashCode() 返回该对象的哈希码值
toString() 返回该对象的字符串表示
在实际开发中,通常希望对象的toString()方法返回的不仅仅是基本信息,而是一些特有的信息。这时重写Object的toString()方法便可以实现
class Animal{
//重写Object类的toString()方法
public String toString() {
return "这是一个动物";
}
}
public class Example01 {
public static void main(String[] args) {
Animal animal = new Animal(); //创建Animal类对象
System.out.println(animal.toString()); //调用toString方法
}
}
匿名内部类
在编写Java程序时,在类里面定义的类称之为内部类(Inner Class),内部类是外部眼泪第一个成员。Java内部类可以分为成员内部类、方法内部类和匿名内部类等
在多态的讲解中,如果方法的参数被定义为一个接口类型,那么就需要定义一个类来实现接口,并根据该类进行对象实例化。除此之外,还可以使用匿名内部类来实现接口。当程序中使用匿名内部类时,在定义匿名内部类的地方往往直接创建该类的一个对象。匿名内部类是实现接口垫 一种简便写法。
普通内部类实现方式:
interface Animal{
void show(); //定义抽象方法show()
}
//定义测试类
public class Example01 {
public static void main(String[] args) {
//定义一个内部类Cat实现Animal接口
class Cat implements Animal{
@Override
public void show() {
System.out.println("嘻嘻...");
}
}
animalshow(new Cat()); //调用animalshow()方法并传入Cat对象
}
public static void animalshow(Animal an) {
an.show();
}
}
匿名内部类的格式:
new 父类(参数列表) 或 父接口(){
//匿名内部类实现部分
}
匿名内部类实现方式
//定义动物类接口
interface Aniaml{ //定义动物类接口
void show();
}
public class Example01 {
public static void main(String[] args) {
//定义匿名内部类作为参数传递给animalshow()方法
animalshow(new Aniaml() {
@Override
public void show() {
System.out.println("喵喵喵喵...");
}
});
}
//定义静态方法animalshow{}
private static void animalshow(Aniaml an) {
an.show();
}
}
分两步来编写匿名内部类,具体如下:
- 在调用animalshow()方法时,在方法的参数位置写上new Aniaml(){},这相当于创建了一个实例对象,并将对象作为参数传给animalshow()方法。在new Aniaml()后面有一对大括号,表示创建的对象为Aniaml的子类实例,该子类是匿名的。
animalshow(new Animal(){});
- 在大括号中编写匿名子类的实现代码
animalshow(new Aniaml() { @Override public void show() { System.out.println("喵喵喵喵..."); } });