继承、重写、super

本文详细介绍了面向对象编程中的继承和重写概念。包括如何定义继承关系、如何使用继承创建对象、重写方法和属性的基本规则,以及super关键字的使用等。

继承

继承 - extends
采用继承机制后,我们用如下方式来定义类:
class 物质{
int 质量;
int get质量(){ return 质量; }
}
class 动物 extends 物质{
}
动物自动继承了物质定义的属性“质量”和方法“get质量

在上例中,我们可以这样来创建动物的实例:
动物 a = new 动物();
也可以:
物质 a = new 动物();

因为动物本身也是物质,所以可以定义为物质类型

除继承的特性外,我们可以给动物增加新的属性或方法
class 动物 extends 物质{
public void move(){}
}
使用时:
动物 a = new 动物();
a.move();

但是
如果我们这样使用:
物质 a = new 动物();
a.move();
是否有问题呢?

因为a的类型为物质类,所以让物质move是不合法的,存在语法错误

要点1】:
可以使用对象的哪些属性或方法,由其定义的类型来决定,而不是由对象的实际类型来决定。如:Animal a=new Dog();
Animal 类是定义类型,Dog类是实际类型,Dog继承Animal,而且子类可以当做父类来使用。

instanceof
用于判断对象的类型
Animal td= new Animal();
System.out.println(td instanceof Object);//true

强制类型转换
Animal x = new Dog();
Dog t = (Dog)x;

Object 类
Object为所有类的父类,除非明确的指定了某一类的父类,否则该类默认继承Object
指定了父类的类会间接继承Object的所有属性和方法,创建的对象也是Object类型的实例,
在垃圾回收中谈到的finalize方法就是Object类中定义的一个方法

重写

重写 override
所谓重写,就是子类对父类中的实例方法进行重新定义的功能,且返回类型,方法名和参数列表都保持不变。且对重写方法的调用主要看实际类型,对重写属性的调用主要看静态类型。
当子类中定义的方法与父类中定义的方法相同时(大括号里的方法体可以不同),称之为方法的重写
class Parent{
void t(){}
}
class Sub extends Parent{
void t(){
System.out.println(“Sub”);
}
}

要点2】:
如果子类重写了父类的某个方法,我们在调用子类对象中的这个方法时,系统将调用子类中定义的方法,无论这个对象被当成什么类型来看待,这个时候一律取决于定义对象的实际类型。如:Sub a=new Sub();
Parent b=new Sub();
a.t();//Sub
b.t();//Sub

当子类中定义了与父类中相同的属性时,称之为属性的重写
class Parent{
int a = 10;
}
class Sub extends Parent{
int a = 20;
}

如果Sub重写了Parent的a属性,则以下调用:
Parent p = new Sub();
System.out.println(p.a);//10
到底会调用Sub中定义的a属性还是Parent中的a属性呢?

【答案】无论对象的实际类型是什么,我们调用对象的属性时总是调用对象被定义成的类型(静态类型)中定义的那个属性。

要点3】:
构造方法不会被继承
class T{
T(){}
}
class Sub extends T{
//不会继承父类中的T()构造方法
}
因为构造方法不能被重写,能被重写的一定能被继承,但是能被继承的就不一定能被重写,如静态方法可以继承,但不可以重写。

super

如果子类重写了父类的方法或属性,而子类对象又希望能够调用被重写的方法或属性呢?
(1)
class Parent{
int a = 10;
void t(){System.out.println(a);}//10
}
class Sub extends Parent{
int a = 20;
void t(){System.out.println(a); }//20
}

在子类中使用super可以引用到父类中定义的属性和方法
(2)
class Parent{
int a = 10;
void t(){System.out.println(a);}//10
}
class Sub extends Parent{
int a = 20;
void t(){System.out.println(super.a); }//10
void tt(){super.t(); }//10
}
(3)
class P{
int a = 10;
}
class S extends P{
int a = 20;
void t(int a){
System.out.println(a); // 5
System.out.println(this.a);//20
System.out.println(super.a);//10
}
}
S s = new S();
s.t(5); //输出什么?

子类的构造方法中,通过super关键字来调用父类的构造方法。
public class Dog extends Animal{
public Dog(String name,int age){
super(name,age);//通过调用父类的构造方法,来完成对相关字段值的初始化
}
}
【注】当构造一个子类对象的时候一定会先调用父类的构造方法来构造父类的对象,没有父类就不会有子类的,调用父类构造方法的语句必须是子类构造方法中的第一条语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值