X  
登录

还没有账号?立即注册

忘记密码?
登陆
X  
注册

已经有账号?马上登陆

获取验证码
重新获取(60s)
立即注册
统计
  • 建站日期:2021-03-10
  • 文章总数:518 篇
  • 评论总数:155 条
  • 分类总数:32 个
  • 最后更新:4月20日
文章 未分类

多态的概述和讲解

梦幻书涯
首页 未分类 正文

/*
 多态练习:猫狗案例
*/
class Animal {
 public void eat(){
  System.out.println("吃饭");
 }
}

class Dog extends Animal {
 public void eat() {
  System.out.println("狗吃肉");
 }
 
 public void lookDoor() {
  System.out.println("狗看门");
 }
}

class Cat extends Animal {
 public void eat() {
  System.out.println("猫吃鱼");
 }
 
 public void playGame() {
  System.out.println("猫捉迷藏");
 }
}

class DuoTaiTest {
 public static void main(String[] args) {
  //定义为狗
  Animal a = new Dog();
  a.eat();
  System.out.println("--------------");
  //还原成狗
  Dog d = (Dog)a;
  d.eat();
  d.lookDoor();
  System.out.println("--------------");
  //变成猫
  a = new Cat();
  a.eat();
  System.out.println("--------------");
  //还原成猫
  Cat c = (Cat)a;
  c.eat();
  c.playGame();
  System.out.println("--------------");
  
  //演示错误的内容
  //Dog dd = new Animal();
  //Dog ddd = new Cat();
  //ClassCastException
  //Dog dd = (Dog)a;
 }
} /*
 ClassCastException:类型转换异常
 一般在多态的向下转型中容易出现
*/
class Animal {
 public void eat(){}
}

class Dog extends Animal {
 public void eat() {}
 
 public void lookDoor() {
 
 }
}

class Cat extends Animal {
 public void eat() {
 
 }
 
 public void playGame() {
  
 }
}

class DuoTaiDemo5 {
 public static void main(String[] args) {
  //内存中的是狗
  Animal a = new Dog();
  Dog d = (Dog)a;
  
  //内存中是猫
  a = new Cat();
  Cat c = (Cat)a;
  
  //内存中是猫
  Dog dd = (Dog)a; //ClassCastException
 }
}/*
 多态的弊端:
  不能使用子类的特有功能。
  
 我就想使用子类的特有功能?行不行?
  行。
  
 怎么用呢?
  A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
  B:把父类的引用强制转换为子类的引用。(向下转型)
  
 对象间的转型问题:
  向上转型:
   Fu f = new Zi();
  向下转型:
   Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
*/
class Fu {
 public void show() {
  System.out.println("show fu");
 }
}

class Zi extends Fu {
 public void show() {
  System.out.println("show zi");
 }
 
 public void method() {
  System.out.println("method zi");
 }

}

class DuoTaiDemo4 {
 public static void main(String[] args) {
  //测试
  Fu f = new Zi();
  f.show();
  //f.method();
  
  //创建子类对象
  //Zi z = new Zi();
  //z.show();
  //z.method();
  
  //你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
  //如果可以,但是如下
  Zi z = (Zi)f;
  z.show();
  z.method();
 }
}/*
 多态的弊端:
  不能使用子类的特有功能。
*/
class Fu {
 public void show() {
  System.out.println("show fu");
 }
}

class Zi extends Fu {
 public void show() {
  System.out.println("show zi");
 }
 
 public void method() {
  System.out.println("method zi");
 }

}

class DuoTaiDemo3 {
 public static void main(String[] args) {
  //测试
  Fu f = new Zi();
  f.show();
  f.method();
 }
}/*
 多态的好处:
  A:提高了代码的维护性(继承保证)
  B:提高了代码的扩展性(由多态保证)
  
 猫狗案例代码
*/
class Animal {
 public void eat(){
  System.out.println("eat");
 }
 
 public void sleep(){
  System.out.println("sleep");
 }
}

class Dog extends Animal {
 public void eat(){
  System.out.println("狗吃肉");
 }
 
 public void sleep(){
  System.out.println("狗站着睡觉");
 }
}

class Cat extends Animal {
 public void eat() {
  System.out.println("猫吃鱼");
 }
 
 public void sleep() {
  System.out.println("猫趴着睡觉");
 }
}

class Pig extends Animal {
 public void eat() {
  System.out.println("猪吃白菜");
 }
 
 public void sleep() {
  System.out.println("猪侧着睡");
 }
}

//针对动物操作的工具类
class AnimalTool {
 private AnimalTool(){}

 /*
 //调用猫的功能
 public static void useCat(Cat c) {
  c.eat();
  c.sleep();
 }
 
 //调用狗的功能
 public static void useDog(Dog d) {
  d.eat();
  d.sleep();
 }
 
 //调用猪的功能
 public static void usePig(Pig p) {
  p.eat();
  p.sleep();
 }
 */
 public static void useAnimal(Animal a) {
  a.eat();
  a.sleep();
 }
 
}

class DuoTaiDemo2 {
 public static void main(String[] args) {
  //我喜欢猫,就养了一只
  Cat c = new Cat();
  c.eat();
  c.sleep();
  
  //我很喜欢猫,所以,又养了一只
  Cat c2 = new Cat();
  c2.eat();
  c2.sleep();
  
  //我特别喜欢猫,又养了一只
  Cat c3 = new Cat();
  c3.eat();
  c3.sleep();
  //...
  System.out.println("--------------");
  //问题来了,我养了很多只猫,每次创建对象是可以接受的
  //但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
  //我们准备用方法改进
  //调用方式改进版本
  //useCat(c);
  //useCat(c2);
  //useCat(c3);
  
  //AnimalTool.useCat(c);
  //AnimalTool.useCat(c2);
  //AnimalTool.useCat(c3);
  
  AnimalTool.useAnimal(c);
  AnimalTool.useAnimal(c2);
  AnimalTool.useAnimal(c3);
  System.out.println("--------------");
  
  //我喜欢狗
  Dog d = new Dog();
  Dog d2 = new Dog();
  Dog d3 = new Dog();
  //AnimalTool.useDog(d);
  //AnimalTool.useDog(d2);
  //AnimalTool.useDog(d3);
  AnimalTool.useAnimal(d);
  AnimalTool.useAnimal(d2);
  AnimalTool.useAnimal(d3);
  System.out.println("--------------");
  
  //我喜欢宠物猪
  //定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
  Pig p = new Pig();
  Pig p2 = new Pig();
  Pig p3 = new Pig();
  //AnimalTool.usePig(p);
  //AnimalTool.usePig(p2);
  //AnimalTool.usePig(p3);
  AnimalTool.useAnimal(p);
  AnimalTool.useAnimal(p2);
  AnimalTool.useAnimal(p3);
  System.out.println("--------------");
  
  //我喜欢宠物狼,老虎,豹子...
  //定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
  //前面几个必须写,我是没有意见的
  //但是,工具类每次都改,麻烦不
  //我就想,你能不能不改了
  //太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
  //改用另一种解决方案。
  
 }
 
 /*
 //调用猫的功能
 public static void useCat(Cat c) {
  c.eat();
  c.sleep();
 }
 
 //调用狗的功能
 public static void useDog(Dog d) {
  d.eat();
  d.sleep();
 }
 */
}/*
 多态:同一个对象(事物),在不同时刻体现出来的不同状态。
 举例:
  猫是猫,猫是动物。
  水(液体,固体,气态)。
  
 多态的前提:
  A:要有继承关系。
  B:要有方法重写。
   其实没有也是可以的,但是如果没有这个就没有意义。
    动物 d = new 猫();
    d.show();
    动物 d = new 狗();
    d.show();
  C:要有父类引用指向子类对象。
   父 f =  new 子();
   
 用代码体现一下多态。
 
 多态中的成员访问特点:
  A:成员变量
   编译看左边,运行看左边。
  B:构造方法
   创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
  C:成员方法
   编译看左边,运行看右边。
  D:静态方法
   编译看左边,运行看左边。
   (静态和类相关,算不上重写,所以,访问还是左边的)
   
  由于成员方法存在方法重写,所以它运行看右边。
*/
class Fu {
 public int num = 100;

 public void show() {
  System.out.println("show Fu");
 }
 
 public static void function() {
  System.out.println("function Fu");
 }
}

class Zi extends Fu {
 public int num = 1000;
 public int num2 = 200;

 public void show() {
  System.out.println("show Zi");
 }
 
 public void method() {
  System.out.println("method zi");
 }
 
 public static void function() {
  System.out.println("function Zi");
 }
}

class DuoTaiDemo {
 public static void main(String[] args) {
  //要有父类引用指向子类对象。
  //父 f =  new 子();
  Fu f = new Zi();
  System.out.println(f.num);
  //找不到符号
  //System.out.println(f.num2);
  
  f.show();
  //找不到符号
  //f.method();
  f.function();
 }
}/*
 看程序写结果:先判断有没有问题,如果没有,写出结果
 
 多态的成员访问特点:
  方法:编译看左边,运行看右边。
  
 继承的时候:
  子类中有和父类中一样的方法,叫重写。
  子类中没有父亲中出现过的方法,方法就被继承过来了。
*/
class A {
 public void show() {
  show2();
 }
 public void show2() {
  System.out.println("我");
 }
}
class B extends A {
 /*
 public void show() {
  show2();
 }
 */

 public void show2() {
  System.out.println("爱");
 }
}
class C extends B {
 public void show() {
  super.show();
 }
 public void show2() {
  System.out.println("你");
 }
}
public class DuoTaiTest4 {
 public static void main(String[] args) {
  A a = new B();
  a.show();
  
  B b = new C();
  b.show();
 }
}/*
 看程序写结果:先判断有没有问题,如果没有,写出结果
*/
class Fu {
 public void show() {
  System.out.println("fu show");
 }
}

class Zi extends Fu {
 public void show() {
  System.out.println("zi show");
 }

 public void method() {
  System.out.println("zi method");
 }
}

class DuoTaiTest3 {
 public static void main(String[] args) {
  Fu f = new Zi();
  //找不到符号
  //f.method();
  f.show();
 }
}/*
 不同地方饮食文化不同的案例
*/
class Person {
 public void eat() {
  System.out.println("吃饭");
 }
}

class SouthPerson extends Person {
 public void eat() {
  System.out.println("炒菜,吃米饭");
 }
 
 public void jingShang() {
  System.out.println("经商");
 }
}

class NorthPerson extends Person {
 public void eat() {
  System.out.println("炖菜,吃馒头");
 }
 
 public void yanJiu() {
  System.out.println("研究");
 }
}

class DuoTaiTest2 {
 public static void main(String[] args) {
  //测试
  //南方人
  Person p = new SouthPerson();
  p.eat();
  System.out.println("-------------");
  SouthPerson sp = (SouthPerson)p;
  sp.eat();
  sp.jingShang();
  System.out.println("-------------");
  
  //北方人
  p = new NorthPerson();
  p.eat();
  System.out.println("-------------");
  NorthPerson np = (NorthPerson)p;
  np.eat();
  np.yanJiu();
 }
}

版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。
版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!

-- 展开阅读全文 --
这篇文章最后更新于2019-6-9,已超过 1 年没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
抽象类的概述和讲解
« 上一篇
final关键字
下一篇 »

发表评论

HI ! 请登录
注册会员,享受下载全站资源特权。
登陆 注册
永远的少年,永远的梦

热门文章