Java中的面向对象编程(2)

前面介绍了面向对象编程中的封装继承组合的内容,这里继续介绍多态的内容。

三、多态

多态涉及到三个方面,向上转型、动态绑定、方法重写。

1.向上转型

首先先明确,向上转型的发生时机有三种:直接赋值、方法传参、方法返回。

1.1直接赋值

假设有两个类,Animal和Dog类,其中Dog类继承自Animal类。

Dog dog = new Dog();

也可以写作:

Dog dog = new Dog();
Animal dog1 = dog;

也可以直接写作:

Animal dog1 = new Dog();

此时 dog1 是一个父类 (Animal) 的引用, 指向一个子类 (Dog) 的实例. 这种写法称为 向上转型。

1.2方法传参
class Animal{
    public void eat(String name){
        System.out.println(name + "正在进食!");
    }
}

class Dog extends Animal{
    public void bite(String name){
        System.out.println(name + "正在咬人!");
    }
}
public class Demo1 {
    public static void main(String[] args) {
       Dog dog = new Dog();
        use(dog);
    }

    private static void use(Animal animal) {
       animal.eat("大黄");
    }
}

这里,dog作为参数是Animal的引用,指向Dog实例。

1.3方法返回
class Animal2{
    public Animal2(){
        System.out.println("Animal2的构造方法被使用了!");
    }
   
}

class Dog2 extends Animal2{
   public Dog2(){
       System.out.println("Dog2的构造方法被使用了!");
   }
}
public class Demo2 {
    public static void main(String[] args) {
      Animal2 animal2 =  use();
    }

    private static Animal2  use() {
        Dog2 dog2 = new Dog2();
        return dog2;
    }
}

这里dog2是Animal2的引用,是Dog2的实例。

2.动态绑定

当子类和父类的方法重名时,调用会出现什么情况呢?

class School {
    public String name;
    public School(String name){
        this.name = name;
    }
    public void printOut(String name){
        System.out.println("这是学校");
        System.out.println(this.name + "的别名是" + name);
    }
}

class Teacher extends School{
    public Teacher(String name){
        super(name);
    }
    public void printOut(String name){
        System.out.println("这是老师");
        System.out.println(this.name + "的小名是" + name);
    }
}
public class Demo3 {
    public static void main(String[] args) {
        School school1 = new School("红星小学");
        School school2 = new Teacher("张老师");
        school1.printOut("红小");
        school2.printOut("花花");
    }
}

打印结果:
这是学校
红星小学的别名是红小
这是老师
张老师的小名是花花

可以看到,school1和school2都是School的引用,但指向的实例不同,所以具体调用到的方法也不同,这就是动态绑定。

3.方法重写

针对刚才的 printOut 方法来说:
子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).
1.要注意区别重写与重载的区别,重载的规则是方法名相同,参数的个数或类型不同。
2. 普通方法可以重写, static 修饰的静态方法不能重写.
3. 重写中子类的方法的访问权限不能低于父类的方法访问权限.
4. 重写的方法返回值类型不一定和父类的方法相同
另外, 针对重写的方法, 可以使用 @Override 注解来显式指定。

写一个用到多态的小程序

class Shape{
    protected double s;
    public Shape(){

    }
    public void calculate(){

    }
}
class Circle extends Shape{
    private  int r;
    public Circle(int r){
        this.r = r;
    }
    public void calculate(){
        System.out.println("圆的面积是:" + 3.14 * r * r);
    }
}
class Rect extends Shape{
    private int a;
    private int b;
    public Rect(int a , int b){
        this.a = a;
        this.b = b;
    }
    public void calculate(){
        System.out.println("矩形的面积是:" + a * b);
    }
}
public class Demo4 {
    public static void main(String[] args) {
        Shape shape1 = new Circle(3);
        Shape shape2 = new Rect(2 , 5);
        shape1.calculate();
        shape2.calculate();
    }
}

打印结果:
圆的面积是:28.259999999999998
矩形的面积是:10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值