【Java答疑一】父类与子类的详解

最近在学Java的继承,发现里面还是有很多坑的,所以借此做个笔记巩固学习。下面以问答的形式展现我学习过程的问题。

1.父类与抽象类区别?

抽象类只能对属性或者方法的申明,不能对其实现。而继承这个类的子类一定要实现抽象类的所有方法。注意,抽象类的方法必定都是抽象的。而父类可以抽象也可以非抽象,可以不用重写所有方法(除抽象方法)
我们同样无法实现抽象类的实例化,这是什么意思,见下段代码:

abstract class Person{
	public abstract void run();
}
class Student extends Person{
	@override//这个相当于注释,编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错 
	void run(){System.out.println("123");}
}
//在主函数中不可以这样定义
Person a=new Person();
//但是可以这样定义
Person a=new Student();

2.super怎么用的?

首先对于super来说:1.可以用来引用直接父类的实例变量。2.可以用来调用直接父类方法。3.可以用于调用直接父类构造函数。
对于1来说,见如下代码:

class Animal {
    String color = "white";
}

class Dog extends Animal {
    String color = "black";

    void printColor() {
        System.out.println(color);// prints color of Dog class
        System.out.println(super.color);// prints color of Animal class
    }
}

public class TestSuper1 {
    public static void main(String args[]) {
        Dog d = new Dog();
        d.printColor();
    }
}

打印结果也是很明显的,就是打印出black 和 white
所以:如果我们打印color属性,它将默认打印当前类的颜色。 要访问父属性,需要使用super关键字指定。
对于2来说,见如下代码:

class Animal {
    void eat() {
        System.out.println("eating...");
    }
}

class Dog extends Animal {
    void eat() {
        System.out.println("eating bread...");
    }

    void bark() {
        System.out.println("barking...");
    }

    void work() {
        super.eat();
        bark();
    }
}

class TestSuper2 {
    public static void main(String args[]) {
        Dog d = new Dog();
        d.work();
    }
}

所以:如果方法被覆盖就可以使用 super 关键字来指定父类方法。
对于3来说:

class Animal {
    Animal() {
        System.out.println("animal is created");
    }
}

class Dog extends Animal {
    Dog() {
        super();
        System.out.println("dog is created");
    }
}

class TestSuper3 {
    public static void main(String args[]) {
        Dog d = new Dog();
    }
}

3.子类没有super是否会默认构造?使用了super是否会改变子类的成员变量?

对于问题一来说,任何子类都会默认构造super,什么意思呢?见如下代码

class Animal {
    Animal() {
        System.out.println("animal is created");
    }
}

class Dog extends Animal {
    Dog() {
        System.out.println("dog is created");
    }
}

public class Test1 {
    public static void main(String args[]) {
        Dog m = new Dog();
    }
}

大家猜猜会出现什么?
运行结果如下:
在这里插入图片描述
是不是不可思议?没有使用super,编译器竟然默认有,和构造方法一样。
如何使用super构造呢?

class Person {
    int id;
    String name;

    Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

class Emp extends Person {
    float salary;

    Emp(int id, String name, float salary) {
        super(id, name);// reusing parent constructor
        this.salary = salary;
    }

    void display() {
        System.out.println(id + " " + name + " " + salary);
    }
}

public class Test2 {
    public static void main(String[] args) {
        Emp e1 = new Emp(1, "ankit", 45000f);
        e1.display();
    }
}


运行结果:
在这里插入图片描述

4.为什么我子类构造方法中有super但是多打印出null?

这就是回到前面的问题了,如果没有super语句,子类会默认构造,也就是说,没有出现构造的方法均会被实现,当然了这个构造就是普通的类名(),否则就会造成null的输出。
如果父类没有无参的构造函数,所以子类需要在自己的构造函数中显示的调用父类的构造函数,即不能使用系统默认的“super()”,而需要显性写出super(xxx)
以下是程序的说明:

public class Main{
    public static void main(String[] args){
        Ming a=new Ming(101,"JACIN");
        System.out.println(a.toString());
        Ming b=new Ming(100,"JACKSON",98);
        System.out.println(b.toString());
    }
}

class Student{
    String name;
    int num;
    Student(int num,String name){
        this.name=name;
        this.num=num;
    }
    Student(){
    }
    Student(String name){
        this.name=name;
    }
    public String toString(){
        return this.num+" "+this.name;
    }
}

class Ming extends Student{
    int num;
    String name;
    int score;
    public Ming(int num,String name){
        super(num,name);
    }
    Ming(int num,String name,int score){
        this.num=num;
        this.name=name;
        this.score=score;
    }
    public String toString(){
        return this.num+" "+this.name;
    }
}

这个运行结果会这样:
在这里插入图片描述
为什么会出现这样的问题呢?我们的疑惑就来了,super到底会不会改变子类的成员变量。这里的程序少了一步,也就是在Ming中super下面加一句,this的使用,否则会出现null
注意这里使用父类的构造方法,所以会根据父类的初始化来改变!

public Ming(int num,String name){
        super(num,name);
        this.name=name;
        this.num=num;
    }
  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值