多态概述:
示例:
/* 多态:可以理解为 存在的多种体现形态. 人:男人,女人 动物:猫,狗. 猫 x=new 猫(); 动物 x=new 猫();//(形象化)相当于来了一只猫(new 猫()),叫的动物 1.多态的体现 父类的引用指向自己的子类对象 或父类的引用可以接收 自己的子类 对象 2.多态的前提 ①必须类与类之间有关系.要么继承,要么实现 ②存在复写(覆盖) 3.多态的好处 多态的出现很大的提高了程序扩展性 4.多态的弊端 提高了扩展性,但是只能使用 父类的引用 访问 父类中的成员 */ abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat()//复写 { System.out.println("吃鱼"); } public void catchMouse()//猫类特有功能 { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat()//复写 { System.out.println("吃骨头"); } public void LookHouse()//猫类特有功能 { System.out.println("看家"); } }class DtDemo { public static void main(String[] args) { //以前写法 /* Cat c =new Cat(); c.eat(); Dog d =new Dog(); d.eat(); */ /* function(new Cat()); function(new Dog()); */ //多态在程序中的表现 //一个事物具有多种形态 // Animal c=new Cat();//既是猫类型,又是动物类型 //c.eat(); function(new Cat()); function(new Dog()); } /* //把方法封装 //代码冗长,有新的动物,需要不断添加方法 public static void function(Cat c) { c.eat(); } public static void function(Dog d) { D.eat(); } */ //前期预先调用功能,后期通过子类实现功能并把子类对象作为参数传递进来,实现后期扩展性 public static void function(Animal a)//相当于Animal a=new Cat(); { a.eat();//此时子类功能复写父类对应功能 //a.catchMouse();//动物具备抓老鼠行为,错误 //子类的功能 } }
多态-转型:
abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void lookHouse() { System.out.println("看家"); } } class DtDemo { public static void main(String[] args) {//动物<-猫 Animal a=new Cat(); //自动类型提升,把猫类型提升动物类型 a.eat(); //向上转型(父类引用指向子类对象) //当想要调用猫的特有方法 //强制将父类引用 转成 子类类型 Cat c=(Cat)a;//向下转型(必须要强转,不会自动向下转型:Cat c = a,例如:猫可以叫猫也可以叫动物,但是动物可能有很多子类(猫,狗..),因此强转为需要的子类型) c.catchMouse();//多态自始至终都是子类对象在做着变化 //以上始终是对猫这个对象的行为 /* 不能将父类对象转成子类类型 Animal a=new Animal(); Cat c=(Cat)a; */ function(new Cat()); function(new Dog()); } public static void function(Animal a) { a.eat(); if(a instanceof Cat)//a指向的对象是否是Cat类的实例 //如果写if(a instanceof Animal),无论Cat还是Dog均满足条件 { Cat c=(Cat)a; c.catchMouse(); } else if(a instanceof Dog) { Dog d=(Dog)a; d.lookHouse(); } } }
多态简单应用:
abstract class Student { //由于学习的内容/方法 不确定-->定义为抽象 public abstract void study(); public void sleep() { System.out.println("躺着睡"); } } //基础班 class BaseStudent extends Student { public void study() { System.out.println("bs Study"); } public void sleep() { System.out.println("坐着睡"); } } //高级班 class AdvStudent extends Student { public void study() { System.out.println("as Study"); } } //把睡觉和学习单独定义在类中一个方法中,简化代码,增加复用性 class StudentDo { public static void doSomething(Student s) //多态体现 { //Student s=new BaseStudent(); s.study(); //Student s=new AdvStudent(); s.sleep(); } } class DtApply { public static void main(String[] args) { StudentDo.doSomething(new BaseStudent()); StudentDo.doSomething(new AdvStudent()); } }
多态中成员特点:
class Father { int num=5; static int i=2; public void method_1() { System.out.print("Father's method_1"); } public void method_2()//被子类继承 { System.out.print("Father's method_2"); } //静态函数 public static void method_4() { System.out.print("Father's method_2"); } } class Son extends Father { //int num=8; static int i=10; public void method_1()//非静态方法复写 { System.out.print("Son's method_1"); } public void method_3()//子类特有 { System.out.print("Son's method_3"); } public static void method_4()//静态方法复写{ System.out.print("Son's method_2"); } } class DtCodeDemo { public static void main(String[] args) { Father f=new Son(); System.out.print("非静态成员函数:\t");f.method_1(); System.out.print("\t"); f.method_2(); System.out.print("\n"); //f.method_3();会编译失败,父类中没有method_3(); System.out.print("静态成员函数:\t"); f.method_4();//打印的父类 System.out.print("\n"); //以下均参考的Father类 System.out.print("成员变量:\t"); System.out.print("num="+f.num+"\n"); System.out.print("静态成员变量:\t"); System.out.print("num="+f.i); } } /* 总结: 在多态中非静态成员函数特点: 在编译时期:参阅引用类型变量所属的类中是否有调用的方法.如果有,编译通过.否则,编译失败 在运行时期:参阅对象所属的类中是否有调用的方法. 简单总结就是:成员函数在多态调用时,编译看左边,运行看右边. 在多态中,成员变量特点: 无论编译和运行,都参考左边(引用型变量所属的类) 在多态中,静态成员函数和静态变量特点: 无论编译和运行,都参考左边(引用型变量所属的类) */关于静态方法是否能复写父类?回答是:子类只能隐藏与父类相同的静态方法而不能复写.
Object中的方法复写:
/* Object:是所有对象的直接或间接父类,传说中的上帝(比喻). 该类中定义的肯定是所有对象都具备的功能. Object 类中已经提供了对对象是否相同的比较方法 如果自定义类中也有比较相同的功能,没有必要重新定义. 只要沿袭父类中的功能,建立自己特有的比较内容即可.(复写) */ //equals方法复写 class Person //extends Object { private int age; public Person(int age) { this.age=age; } public boolean equals(Object o)//根据需要,直接复写掉Object类中的 //equals方法,而不再定义与此类似的功能 { if(!(o instanceof Person)) return false;Person p=(Person)o;//向下转型 return this.age==p.age; } } class ObjectDemo { public static void main(String[] args) { System.out.println(new Person(10).equals(new Person(20))); } }
//toStirng()方法
class Person { } class ObjectDemo2 { public static void main(String[] args) { Person p=new Person(); Class c=p.getClass();//返回p指向对象所在的类(或者叫类文件对象) //Class 类的实例表示正在运行的 Java 应用程序中的类和接口 System.out.println(c.getName());//以 String 的形式返回此 Class 对象所表示的实体名称。 System.out.println(p.toString());//所属类名@十六进制哈希值 System.out.println(c.getName()+"@"+Integer.toHexString(p.hashCode()));//得出以上结果 } } /* 关于Class类 例如: A.class文件和B.class文件 共性: 都有名称,文件中都有构造函数 Class类来描述这些class文件 就好像张三,李四->描述为Person类(共性有name,age...) */