测试类 :
package com.day22.obj;
public class TestObj {
//面向对象的多态性
public static void main(String[] args) {
//基本调用
Person person =new Person();
person.eat();
Man man =new Man();
// 重写父类
man.eat();
//调用父类
man.age=25;
man.earnMoney();
//*************************//
//对象的多态性
// 只要是Person的子类 右边都可以来new 使用
//父类的引用指向子类的对象
//左边是父类的声明 右边是new 子类的对象
Person p2=new Man();
//Person p3=new Woman();
//为什么要这样声明?
//调用的是子类的方法
// 多态的使用
//当调用子父类同名同参数的方法时 实际执行的是子类重写的父类方法 --- 虚拟方法调用
p2.eat();
p2.walk();
//这样左边声明的父类 右表是 new 的子类 是不能调用子类特有的方法
//只能调用子类 重写父类的方法
//p2.earnMoney();
//俗语 编译看左边 运行看右边
// 解释 程序编译的时候 程序看的是 左边声明的类 运行的时候 会去运行 new 出来对象的方法 一般是子类重写父类的方法
//多态性的使用前提
// 1. 要有类的继承关系
// 2. 子类必须要重写父类方法 (为什么要去重写父类呢?)
// 如果不去重写父类的方法 在声明父类的关键字的时候
/// 为什么不直接new一个父类呢 而是 左边声明父类 右边调用子类 这样声明 一般就是为了调用子类重写父类的方法
//为什么面向对象会用多态性
// 三大特性 封装 继承 多态
// 使用场景
//举例类名 AnimalTest
//多态性适用于方法
//多态性不适用属性
//现在在 Man 里定义一个id Person也定义一个id
//现在调用多态声明的对象 他实际调用的是左边声明的属性 而不会去调用子类声明的属性
//属性 声明和运行 都看左边
System.out.println(p2.id); //1002
//重写和重载的不同处
//重写 是针对子类重写父类 其参数也一致
//重载 是针对自己有相同的方法名 而参数不同 子类也可以去重载父类 同名不同参数的方法
}
}
父类:
package com.day22.obj;
public class Person {
String nameString;
int age;
int id=1002;
public void eat() {
System.out.println("吃饭");
}
public void walk() {
System.out.println("走路");
}
}
子类一:
package com.day22.obj;
public class Man extends Person{
boolean isSmoking;
int id=1001;
public void earnMoney() {
System.out.println("挣钱");
}
public void eat() {
System.out.println("吃饭多吃肉");
}
public void walk() {
System.out.println("走路好男人");
}
}
子类二:
package com.day22.obj;
public class Woman extends Person{
boolean isBeauty;
public void goShopping() {
System.out.println("购物");
}
public void eat() {
System.out.println("女人 -----吃饭多吃肉");
}
public void walk() {
System.out.println("走路好女人");
}
}
多态的使用场景例子:
package com.day22.obj;
import java.sql.Connection;
//多态性的使用
//举例一
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test=new AnimalTest();
//在main里调用 声明的func方法
//func 方法传入的是一个Animal这个对象类型
//当往这个方法里传入继承他不同的子类时 调用的是不同的重写的方法
// 这便展示出来多态的魅力
test.func(new Dog());
test.func(new Cat());
}
//定义一个父类的形参 Animal对象
public void func(Animal animal) {
animal.eat();
animal.shout();
}
//如果没有多态性的表现形式
//如果你想调用 这两个类的方法 你就要造重载两个这样的方法 有100个就要造重载100个 这样能累死人
//有了多态性 就可以省去这么多重载的方法
public void func(Dog dog) {
dog.eat();
dog.shout();
}
public void func(Cat cat) {
cat.eat();
cat.shout();
}
}
class Animal{
public void eat() {
System.out.println("动物吃饭");
}
public void shout() {
System.out.println("动物叫");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗吃骨头");
}
public void shout() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void shout() {
System.out.println("喵喵喵");
}
}
//举例二
class Order{
//现在这个形参时 Object类型 意味着只要传入的对象都可以使用
// Object 根对象
public void method(Object obj) {
}
}
//举例三
class Driver{
public void getConn(Connection conn) { //形参声明的时父类的类 实际调用的是子类的方法
//如果传入的是 mysql new的类 这个方法里就是使用的 mysql的方法
//如果传入的是 oracle new的类 这个方法里就是使用的 oracle的方法
}
}