Java学习笔记 继承与抽象类:域隐藏与方法覆盖

1.域隐藏

什么是域隐藏
在子类中,定义与父类同名的成员变量

class Person{
    protected String name;
    protected int age;
    public void show(){
        System.out.println("姓名"+name+"年龄"+age);
    }
}
class Student extends Person {
    private String department;
    int age = 20;//与父类age同名(域隐藏)
    public Student(String name,String department){
        this.department=department;
        this.name = name;
        super.age = 25;
        System.out.println("子类中的成员变量age="+age);
        super.show();
        System.out.println("系别"+department);
    }
}
public class hide {
    public static void main(String[] args) {
        Student stu = new Student("李小四","信息系");
    }
}

在这里插入图片描述
可以看到,通过继承,子类可以把父类中所有的域和方法都继承下来成为自身的域和方法,但是子类也可以根据需要定义与继承自父类的同名的域,则在子类中只能访问到子类中定义的域而不能访问到继承自父类的同名域,这种情况称为域的隐藏。子类中的方法不能访问父类中被隐藏的域。

2.方法覆盖

什么是覆盖
在子类中定义名称参数个数类型均与父类完全相同的方法
用以重写父类同名的方法
方法覆盖方法的重载都是面向对象多态性的体现
注意不能覆盖父类中声明的final方法

案例:覆盖的实现

class Person{
    protected String name;
    protected int age;
    public Person(){}
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void show(){
        System.out.println("姓名"+name+"年龄"+age);
    }
}
class Student2 extends Person {
    private String department;
    public Student2(String name,int age,String department){
        super(name,age);
        this.department = department;
    }
    public void show(){//覆盖父类中的同名方法
        System.out.println("系别"+department);
    }
}
public class cover {
    public static void main(String[] args) {
        Student2 stu = new Student2("王二",24,"信息系");
        stu.show();
    }
}

在子类中覆盖父类的方法时,可扩大父类中的方法权限,但不能缩小其权限

3.覆盖中的特殊情况

用父类的变量访问子类的成员
只限于覆盖的情况发生
格式:
父类 对象 = new 子类();
对象.子类方法;
Person per = new Student(“王二”,24,“信息系”);
per.show();
这是向上转型

编程练习

class Animal
{   void play()
   {
      System.out.println("我是动物,我会很多本领");
    }
} 
【代码1//定义Animal类的子类Bird,覆盖Animal类的play( )方法,并在play( )方法中输出"我是小鸟,我能飞翔"
  
【代码2//定义Animal类的子类Fish,覆盖Animal类的play( )方法,并在play( )方法中输出"我是小鱼,我能游泳"

class Overriding
{  public static void main(String[] args)
  {   Animal s1=new Animal();
      Bird s2=new Bird();
      Fish s3=new Fish();
      s1.play();
      s2.play();
      s3.play();
   }
}

答案

class Animal {
    void play() {
        System.out.println("我是动物,我会很多本领");
    }
}

class Bird extends Animal//定义Animal类的子类Bird,覆盖Animal类的play( )方法,并在play( )方法中输出"我是小鸟,我能飞翔"
{
    void play() {
        System.out.println("我是小鸟,我能飞翔");
    }
}
class Fish extends Animal//定义Animal类的子类Fish,覆盖Animal类的play( )方法,并在play( )方法中输出"我是小鱼,我能游泳"
{
    void play() {
        System.out.println("我是小鱼,我能游泳");
    }
}

class Train {
    public static void main(String[] args) {
        Animal s1 = new Animal();
        Bird s2 = new Bird();
        Fish s3 = new Fish();
        s1.play();
        s2.play();
        s3.play();
    }
}

这里可以优化一下

class Train {
    public static void show(Animal a) {
        a.play();
    }
    public static void main(String[] args) {
        show(new Bird());
        show(new Fish());
    }
}

利用向上转型这里更加简洁明了

–下面是拓展:
向上转型时,父类只能调用父类方法或者子类覆写后的方法,而子类中的单独方法则是无法调用的.
那么向上转型到底有什么用呢,到目前为止我们不仅看不到它的好处,反而发现使用了向上转型后反而不能调用子类所特有的方法了。那么向上转型的作用到底是什么呢,我们一起来看下面的代码:

class Car {
    public void run() {
        System.out.println("这是父类run()方法");
    }

    public void speed() {
        System.out.println("speed:0");
    }

}

class BMW extends Car {
    public void run() {
        System.out.println("这是BMW的run()方法");
    }

    public void speed() {
        System.out.println("speed:80");
    }
}

public class Benz extends Car {
    public void run() {
        System.out.println("这是Benz的run()方法");

    }

    public void speed() {
        System.out.println("speed:100");
    }

    public void price() {
        System.out.println("Benz:800000$");
    }

    public static void main(String[] args) {
        show(new Benz());//向上转型实现
        show(new BMW());
    }

    public static void show(Car car) {//父类实例作为参数
        car.run();
        car.speed();
    }
}

上面代码中

    public static void main(String[] args) {
        show(new Benz());
        show(new BMW());
    }

    public static void show(Car car) {
        car.run();
        car.speed();
    }

就体现了向上转型的优点,这也体现了Java抽象编程的思想。如果此处没有向上转型,要实现show每个子类的功能,那么有几个子类就要写多少函数。代码如下:

    public static void main(String[] args) {
        show(new Benz());
        show(new BMW());
    }

    public static void show(Benz benz) {
        benz.run();
        benz.speed();
    }
    public static void show(BMW bmw) {
        bmw.run();
        bmw.speed();
    }

敲黑板
向上转型虽然使代码变得简洁,体现了JAVA的抽象编程思想,但是也出现了上面提到的子类无法调用其独有的方法,这要怎么解决呢?所以就有了与之对应的向下转型,弥补了向上转型所带来的缺陷。

转载自:https://blog.csdn.net/TNTZS666/article/details/80273986

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值