1. 多态 问题引入 使用传统的方法来解决(private 属性) 传统的方法带来的问题是什么? 如何解决? 问题是: 代码的复用性不高,而且不利于代码维护 解决方案: 引出我们要讲解的多态
1. 多态 问题引入
使用传统的方法来解决(private 属性)
传统的方法带来的问题是什么? 如何解决?
问题是: 代码的复用性不高,而且不利于代码维护
解决方案: 引出我们要讲解的多态
1.1 普通方法 305
代码在com.stulzl.poly_.包中
测试Poly01
package com.stulzl.poly_;
public class Poly01 {
public static void main(String[] args) {
Master tom = new Master("汤姆");
Dog dog = new Dog("大黄");
Bone bone = new Bone("大棒骨");
tom.feed(dog,bone);
System.out.println("=============");
Cat cat = new Cat("小花猫");
Fish fish = new Fish("黄花鱼");
tom.feed(cat,fish);
}
}
主人类Master
package com.stulzl.poly_;
public class Master {
private String name;
//构造器
public Master(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//完成主人给小狗喂骨头
public void feed(Dog dog,Bone bone){
System.out.println("主人 "+name+" 给"+dog.getName()+" 吃"+bone.getName());
}
//完成主人给小猫喂鱼
public void feed(Cat cat,Fish fish){
System.out.println("主人 "+name+" 给"+cat.getName()+" 吃"+fish.getName());
}
}
父类Food
package com.stulzl.poly_;
public class Food {
private String name;
//构造器
public Food(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类Fish
package com.stulzl.poly_;
public class Fish extends Food {
public Fish(String name) {
super(name);
}
}
子类Bone
package com.stulzl.poly_;
public class Bone extends Food {
public Bone(String name) {
super(name);
}
}
父类Animal
package com.stulzl.poly_;
public class Animal {
private String name;
//构造器
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类 Cat
package com.stulzl.poly_;
public class Cat extends Animal{
public Cat(String name) {
super(name);
}
}
子类Dog
package com.stulzl.poly_;
public class Dog extends Animal{
public Dog(String name) {
super(name);
}
}
2. 多态基本介绍 306
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的
2.1 多态的具体体现
2.2.1 方法的多态 306
代码在com.stulzl.poly_method.包中
PolyMethod
package com.stulzl.poly_method;
public class PolyMethod {
public static void main(String[] args) {
//方法重载体现多态
A a = new A();
//这里我们传入不同的参数,就会调用不同 sum 方法,就体现多态
System.out.println(a.sum(10, 20));
System.out.println(a.sum(10, 20, 30));
//方法重写体现多态
B b = new B();
a.say();
b.say();
}
}
class B { //父类
public void say() {
System.out.println("B say() 方法被调用...");
}
}
class A extends B {//子类
public int sum(int n1, int n2) {//和下面 sum 构成重载
return n1 + n2;
}
public int sum(int n1, int n2, int n3) {
return n1 + n2 + n3;
}
public void say() {
System.out.println("A say() 方法被调用...");
}
}
2.2 对象的多态(重点)307
代码在com.stulzl.poly_objpoly.包中
测试PolyObject
package com.stulzl.poly_objpoly;
//对象的多态
public class PolyObject {
public static void main(String[] args) {
//体验对象多态特点
//编译类型就是 Animal , 运行类型 Dog
Animal animal = new Dog();
animal.cry();//小狗汪汪叫//因为运行时 , 执行到改行时,animal 运行类型是 Dog,
// 所以 cry 就是 Dog 的 cry
//animal 编译类型 Animal,运行类型就是 Cat
animal=new Cat();
animal.cry();//小猫喵喵叫……
}
}
父类Animal
package com.stulzl.poly_objpoly;
public class Animal {//父类
public void cry(){
System.out.println("Animal cry() 动物在叫……");
}
}
子类Cat
package com.stulzl.poly_objpoly;
public class Cat extends Animal{//子类
public void cry() {
System.out.println("Cat cry() 小猫喵喵叫……");
}
}
子类Dog
package com.stulzl.poly_objpoly;
public class Dog extends Animal{//子类
public void cry(){
System.out.println("Dog cry() 小狗汪汪叫……");
}
}
3. 多态快速入门
3.1 使用多态的机制来解决主人喂食物的问题 308
代码在com.stulzl.poly_.包中
测试Poly01
package com.stulzl.poly_;
//使用多态的机制来解决主人喂食物的问题 308
public class Poly01 {
public static void main(String[] args) {
Master tom = new Master("汤姆");
Dog dog = new Dog("大黄~");
Bone bone = new Bone("大棒骨");
tom.feed(dog,bone);
System.out.println("=============");
Cat cat = new Cat("小花猫~");
Fish fish = new Fish("黄花鱼");
tom.feed(cat,fish);
System.out.println("=============");
Pig pig = new Pig("小花猪");
Food rice = new Food("米饭");
tom.feed(pig,rice);
}
}
主人类Master
package com.stulzl.poly_;
public class Master {
private String name;
//构造器
public Master(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//使用多态机制,可以统一的管理主人喂食的问题
//animal编译类型是Animal,可以指向(接收)Animal的子类对象
//food编译类型是Food,可以指向(接收)Food的子类对象
public void feed(Animal animal,Food food){
System.out.println("主人 "+name+" 给"+animal.getName()+" 吃"+food.getName());
}
// //完成主人给小狗喂骨头
// public void feed(Dog dog,Bone bone){
// System.out.println("主人 "+name+" 给"+dog.getName()+" 吃"+bone.getName());
// }
// //完成主人给小猫喂鱼
// public void feed(Cat cat,Fish fish){
// System.out.println("主人 "+name+" 给"+cat.getName()+" 吃"+fish.getName());
// }
}
父类Food
package com.stulzl.poly_;
public class Food {//父类
private String name;
//构造器
public Food(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类Fish
package com.stulzl.poly_;
public class Fish extends Food {
public Fish(String name) {
super(name);
}
}
子类Bone
package com.stulzl.poly_;
public class Bone extends Food {
public Bone(String name) {
super(name);
}
}
子类Rice
package com.stulzl.poly_;
public class Rice extends Food{
public Rice(String name) {
super(name);
}
}
父类Animal
package com.stulzl.poly_;
public class Animal {//父类
private String name;
//构造器
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
子类Cat
package com.stulzl.poly_;
public class Cat extends Animal{
public Cat(String name) {
super(name);
}
}
子类Dog
package com.stulzl.poly_;
public class Dog extends Animal{
public Dog(String name) {
super(name);
}
}
子类Pig
package com.stulzl.poly_;
public class Pig extends Animal {
public Pig(String name) {
super(name);
}
}
4. 多态的注意事项 309
4.1 细节1
多态的前提是:两个对象(类)存在继承关系
多态的向上转型
多态的向下转型
代码在com.stulzl.poly_detail.包中
测试PolyDetail
package com.stulzl.poly_detail;
//多态细节309
public class PolyDetail {
public static void main(String[] args) {
//向上转型: 父类的引用指向了子类的对象 309
//语法:父类类型引用名 = new 子类类型();
Animal animal = new Cat();
Object obj = new Cat();//可以吗? 可以 Object 也是 Cat 的父类
//向上转型调用方法的规则如下:
//(1)可以调用父类中的所有成员(需遵守访问权限)
//(2)但是不能调用子类的特有的成员
//因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//animal.catchMouse();错误
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
//然后调用,规则我前面我们讲的方法调用规则一致
animal.eat();//猫吃鱼..
animal.run();//跑
animal.show();//hello,你好
animal.sleep();//睡
//希望可以调用 Cat 的 catchMouse 方法 310
//多态的向下转型
//(1)语法:子类类型 引用名 =(子类类型)父类引用;
//问一个问题? cat 的编译类型 Cat, 运行类型是 Cat
Cat cat = (Cat) animal;
cat.catchMouse();//猫抓老鼠
//(2)要求父类的引用必须指向的是当前目标类型的对象 310
//此句的意思是,之前animal指向了Cat,但是你要强转只能转向Cat类
}
}
父类Animal
package com.stulzl.poly_detail;
public class Animal {//父类
String name = "动物";
int age = 10;
public void sleep(){
System.out.println("睡");
}
public void run(){
System.out.println("跑");
}
public void eat(){
System.out.println("吃");
}
public void show(){
System.out.println("hello,你好");
}
}
子类Cat
package com.stulzl.poly_detail;
public class Cat extends Animal{
public void eat(){//方法重写
System.out.println("猫吃鱼");
}
public void catchMouse(){//Cat 特有方法
System.out.println("猫抓老鼠");
}
}
4.2 细节2 310
属性没有重写之说!属性的值看编译类型
代码在com.stulzl.poly_detail02.包中
测试PolyDetail02
package com.stulzl.poly_detail02;
import javax.security.auth.Subject;
//属性没有重写之说!属性的值看编译类型
public class PolyDetail02 {
public static void main(String[] args) {
//属性没有重写之说!属性的值看编译类型
Base base = new Sub();//向上转型
System.out.println(base.count);//? 10,看编译类型
Sub sub = new Sub();
System.out.println(sub.count);//20
}
}
class Base{//父类
int count=10;//属性
}
class Sub extends Base{//子类
int count=20;//属性
}
【文章原创作者:响水网站开发 http://www.1234xp.com/xiangshui.html 复制请保留原URL】