java基础14 多态(及关键字:instanceof)
面向对象的三大特征:
1.封装 (将一类属性封装起来,并提供set()和get()方法给其他对象设置和获取值。或者是将一个运算方法封装起来,其他对象需要此种做运算时,给此对象调用)
2.继承 (继承关系通过extends关键字体现)
3.多态 (父类的引用指向子类的对象,或者接口的引用类型变量指向接口实现类的对象)
1、多态的含义
父类的引用指向子类的对象,或者接口的引用类型变量指向接口实现类的对象
2、多态的应用
1.多态应用于形式参数的时候,可以接收更多类型的数据.
2.多态用于返回值时,可以返回更多类型的数据.
3、多态的好处
提高了代码的拓展性.
4、多态的弊端
虽然提高了扩展性,但是只能使用父类引用指向父类成员。
5、多态的前提
类与类之间有关系,继承或者实现
6、多态体现
1:父类引用变量指向了子类的对象
2:父类引用也可以接受自己的子类对象
7、类型转换场景的问题
java.lang.ClassCaseException.类型转换失败
8、附录
如果需要访问子类特有的成员,那么需要进行强制类型转换
1、基本数据类型转换:
小数据类型------>大数据类型 自动转换
大数据类型------>转小数据类型 强制类型转换
2、引用类型转换:
小数据类型------->大数据类型 自动转换
大数据类型------->转小数据类型 强制类型转换
9、实现关系下的多态
接口的引用类型变量指向接口实现类的对象
格式: 接口 变量 = new 接口实现类的对象
例子:
1 interface Dao { //接口的方法全部都是非静态的方法 2 public void add(); 3 public void delete(); 4 } 5 6 //接口的实现类 7 class UserDao implements Dao{ 8 public void add(){ 9 System.out.println("添加员工!!!"); 10 } 11 public void delete(){ 12 System.out.println("删除员工"); 13 } 14 } 15 16 class Demo2 { 17 public static void main(String[] args) { 18 //实现关系下的多态 19 Dao d=new UserDao(); //接口的引用类型变量指向接口的实现类的对象 20 d.add(); 21 d.delete(); 22 } 23 }
10、实例
例子1:
/* 1:Father类 1:非静态成员变量x 2:静态成员变量y 3:非静态方法eat,方法体输出父类信息 4:静态方法speak();方法体输出父类信息 2:Son类 1:非静态成员变量x 2:静态成员变量y 3:非静态方法eat,方法体输出子类信息 4:静态方法speak();方法体输出子类信息 */ class Father { int x = 1; static int y = 2; void eat() { System.out.println("开吃"); } static void speak() { System.out.println("小头爸爸"); } } class Son extends Father { int x = 3; static int y = 4; void eat() { System.out.println("大头儿子很能吃"); } static void speak() { System.out.println("大头儿子。"); } } class Demo10 { public static void main(String[] args) { Father f = new Son(); // 父类引用指向了子类对象。 System.out.println(f.x); //返回结果:1 System.out.println(f.y); //返回结果:2 f.eat(); // 输出的是子类的方法 f.speak(); // 输出的是父类的方法 } }
解析:子类(Son)继承父类(Father)
1:创建Father f=new Son();
1:这就是父类引用指向了子类对象。
2:问f.x=?(非静态)
3:问f.y=?(静态)
4:问f.eat()输出的是子类还是父类信息?(非静态)
5:问f.speak()输出的是子类还是父类信息?(静态)
总结:
1:当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量
2:当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量 所以:父类和子类有相同的成员变量,多态下访问的都是父类的成员变量。
3:当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。
4:当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。
例子2:
1 //动物类 2 abstract class Animal{ 3 String name; 4 public Animal(String name){ 5 this.name=name; 6 } 7 8 public abstract void run(); //抽象方法 9 } 10 //老鼠类 11 class Mouse extends Animal{ 12 public Mouse(String name){ //调用父类构造器,目的:获取成员变量name中的值 13 super(name); 14 } 15 public void run(){ //重写父类的抽象方法 16 System.out.println(name+"四条腿慢慢走"); 17 } 18 19 public void dig(){//Mouse子类特有的方法 20 System.out.println(name+"老打洞..."); 21 22 } 23 } 24 //鱼类 25 class Fish extends Animal{ 26 public Fish(String name){ 27 super(name); 28 } 29 public void run(){ //重写父类的抽象方法 30 System.out.println(name+"摇着尾巴游啊游..."); 31 } 32 public void bubble(){ //Fish子类特有的方法 33 System.out.println(name+"吹泡泡...."); 34 } 35 } 36 37 class Demo6 { 38 public static void main(String[] args) { 39 Animal a=new Mouse("米老鼠");//多态,父类的引用指向子类的对象 40 a.run(); 41 //a.dig(); //报错 42 43 Mouse m=(Mouse)a;//强制类型转换 44 m.dig(); //如果直接用a.dig()的话,会报错,因为是多态(父类中没有dig()方法),所以要强制转换类型 45 46 Animal a1=new Fish("金枪鱼"); 47 Fish f=(Fish)a1; 48 print(f); 49 } 50 51 //需求,定义一个函数可以接收任意类型的动物对象,在函数的内部要调用到动物特有的方法 52 //instanceof 53 public static void print(Animal a){//Animal a=new Fish(); 54 if(a instanceof Fish){ 55 Fish f=(Fish)a; 56 f.bubble(); 57 }else if(a instanceof Mouse){ 58 Mouse m=(Mouse)a; 59 m.dig(); 60 }else{ 61 System.out.println("输入错误"); 62 } 63 } 64 }
1 //形状类 2 abstract class MyShape{//抽象类 3 public abstract void getLength(); //抽象方法 4 public abstract void getArea(); //抽象方法 5 } 6 //圆形 7 class Circle extends MyShape{ 8 public final static double PI=3.14; //常量 9 double r; 10 public Circle(double r){ 11 this.r=r; 12 } 13 14 public void getLength(){ 15 System.out.println("这是圆形的周长"+2*PI*r); 16 } 17 public void getArea(){ 18 System.out.println("这是圆形的面积"+PI*r*r); 19 20 } 21 } 22 //矩形 23 class Rect extends MyShape{ 24 int width; 25 int height; 26 27 public Rect(int width,int height){ 28 this.width=width; 29 this.height=height; 30 } 31 public void getLength(){ 32 System.out.println("这是矩形的周长"+2*(width+height)); 33 } 34 public void getArea(){ 35 System.out.println("这是矩形的面积"+width*height); 36 } 37 public void t(){ 38 System.out.println("来咬我啊!!!"); 39 } 40 } 41 42 class Demo5 { 43 public static void main(String[] args) {
44 MyShape mp=new Circle(3.0);//多态,父类的引用指向了子类的对象 45 mp.getLength(); 46 mp.getArea();
47 //方法2
48 Circle c = new Circle(3.0); 49 Rect r = new Rect(5,8); 50 MyShape m = new Rect(8,3); 51 //m.t(); //报错,此处需要强制类型转换 52 print(r); 53 print(c);//new Circle(3.0) 54 } 55 56 //需求1.定义一个函数可以接收任意类型的对象,并且打印图形的面积与周长 57 public static void print(MyShape s){//相当于:MyShape s=new Circle(3.0) 58 s.getLength(); 59 s.getArea(); 60 MyShape m = getShape(1); 61 } 62 63 //需求2:定义一个函数可以返回任意类型的图形对象. 64 public static MyShape getShape(int i){ 65 66 if(i == 1){ 67 return new Circle(2.0); 68 }else if(i == 0){ 69 return new Rect(6,9); 70 }else{ 71 return null; 72 } 73 } 74 }
原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:http://www.cnblogs.com/dshore123/p/8891998.html 欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!) |