1.什么是多态
所谓多态就是一个对象在不同环境下表现出来的多种形态,在程序中是表现父类引用指向子类对象
2.多态的使用
在抽象类中使用
abstract class Animal {
public abstract void eat();
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class DolymorphicDemo1 {
public static void main(String[] args) {
Animal animal = new Dog();
animal.eat();
}
}
在接口中使用
interface Fun {
void run();
}
class SunFun implements Fun {
@Override
public void run() {
System.out.println("开始跑");
}
}
public class DolymorphicDemo2 {
public static void main(String[] args) {
Fun fun = new SunFun();
fun.run();
}
}
在参数列表中使用
//定义接口
public interface UserDao {
void save(String name);
}
//定义实现
public class UserDaoImpl implements UserDao{
@Override
public void save(String name) {
System.out.println(name);
}
}
//定义工厂类
public class UserDaoFactory {
public UserDao build(UserDao userDao) {
if (userDao instanceof UserDaoImpl) {
return new UserDaoImpl();
}
return null;
}
}
3.多态的缺点
在多态的情况下,不能使用子类特有的方法
public class UserDaoImpl implements UserDao{
@Override
public void save(String name) {
System.out.println(name);
}
public void add() {
System.out.println("add");
}
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
userDao.add(); //此处报错
}
}
在使用多态情况下想使用子类特有方法时,会报错,如何希望不报错,那么我们就需要进行向下类型转换
public class UserDaoImpl implements UserDao{
@Override
public void save(String name) {
System.out.println(name);
}
public void add() {
System.out.println("add");
}
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
UserDaoImpl udi = (UserDaoImpl) userDao;
udi.add();
udi.save("李四");
}
}
当我们把父类引用对象强转为子类对象后,就可以调用子类特有方法以及父类中的方法了。但这种也就降低了程序的灵活性了
在进行向下转换时,为了避免转换时抛出异常,我们通常会使用 instanceof 运算符来进行判断
abstract class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
public class AnimalDemo {
public static void main(String[] args) {
//多态
Animal animal = new Dog();
//向下类型转换
Dog dog = (Dog) animal;
if (dog instanceof Animal) {
//Cat cat = (Cat) dog;
}
}
}
instanceof 运算符的是使用格式为:要转换的对象 instanceof 需要判断的对象, 返回的是一个布尔值,true 表示可以转换,false 表示不能转换
4.面试题
说出下面代码的输出结果
class Father {
public int a = 5;
public void show() {
System.out.println("Fatther show()");
}
public static void say() {
System.out.println("Father say");
}
}
class Sun extends Father {
public int a = 10;
public void show() {
System.out.println("Sun show");
}
public static void say() {
System.out.println("Father say");
}
}
public class Demo {
public static void main(String[] args) {
/*Father f = new Father();
System.out.println(f.a); // 5
f.show();
Sun sun = new Sun();
System.out.println(sun.a); // 10
sun.show(); */
Father father = new Sun();
System.out.println(father.a); // 5
father.show();
father.say();
}
}
总结:
1.成员变量在编译时看等号的左边,运行时也看等号的左边
2.实例方法在编译时看等号的左边,运行时看等号的右边
3.静态方法在编译时看等号的左边,运行时也看等号的左边