java继承
1什么是继承?
这里的继承我们可以同生活中的继承遗产来理解,长辈去世,子辈继承老一被留下的东西,在老一辈的基础上进行奋斗,其实继承的基本意思和这个也差不多
不扯皮了我们来正经的说说什么是继承。
继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。
使用继承的优点:
1.多个类具有相同的行为时,将这些共同点抽到同一个类中,那些类继承这个类即可,就是增加了代码的可复用性
2.是多态的前提
继承的叫子类,而被继承叫交超类,父类或基类
如上图中的食草动物和食肉动物是动物的子类,而兔子和🐏是是食草动物的子类,狮子和豹子是食肉动物的子类
2继承的格式
class fu{
}
class zi extends fu{
}
下面通过一段代码来为大家演示继承
public class Audi extends Car {
}
public class Car {
public void run(){
System.out.println("我是一辆车");
}
}
public class Test {
public static void main(String[] args) {
Audi auid = new Audi();
auid.run();
}
}
输出结果:
我们可以看到子类Audi成功继承了父类的run()方法
3继承中成员变量的一些特点及注意事项
3.1如果子类与父类的成员变量名不重名,直接调用即可
public class Car {
int num=100;
}
public class Audi extends Car {
int num2=200;
public void show(){
System.out.println("num="+num);
System.out.println("num2="+num2);
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果:
我们可以看到子类成功调用了父类的成员变量num
3.2子类与父类成员变量重名的情况
这和不重名的区别就大了
public class Audi extends Car {
int num=200;
public void show(){
System.out.println("num="+num);
System.out.println("num="+num);
}
}
public class Car {
int num=100;
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果:
我们可以看到打印的是子类Audi的num值
那么这就导致了一个问题,如果子类和父类重名了,我怎么来调用父类的成员变量呢????
在子类与父类出现重名情况的时候要要使用super关键字来修饰成员变量,类似关键字this
下面我用刚刚的例子再来演示一遍
public class Audi extends Car {
int num=200;
public void show(){
System.out.println("子类num="+num);
System.out.println("父类num="+super.num);
}
}
public class Car {
int num=100;
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果:
我们可以看到成功调用了父类的成员变量
4下面我们来讲继承中的成员方法
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对 应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法
4.1子类中没有要调用的方法,向上找父类中的方法
public class Audi extends Car {
}
public class Car {
public void show(){
System.out.println("这是car");
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果
4.1子类方法与父类方法重名
public class Audi extends Car {
public void show(){
System.out.println("这是Audi");
}
}
public class Car {
public void show(){
System.out.println("这是car");
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果
我们可以看到子类调用了自己的show方法
有同学可能又会问了要是我又想调用父类方法怎么办,老规矩还是使用super关键字
public class Audi extends Car {
public void show(){
super.show();
System.out.println("这是Audi");
}
}
public class Car {
public void show(){
System.out.println("这是car");
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.show();
}
}
结果
成功调用了父类方法
这里的方法重名在java里有另一个名称叫做重写(override)
这里介绍一下重写的定义:子类方法中出现父类一样的方法时(返回值类型,方法名和参数列表都相同)会出现覆盖效果,也称为重写或复写,声明不变,重新实现,我们在重写的方法前面加上“@override”关键字来防止我们写错
public class Audi extends Car {
@Override
public void show(){
System.out.println("这是Audi");
}
}
重写的注意事项
1子类方法覆盖父类方法,必须保证权限大于等于父类方法
2子类方法覆盖父类方法,必须保证返回值类型、函数名和参数列表都要一模一样。
5构造方法
所谓构造方法就是初始化对象的方法
我们先明确两点
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构 造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。我用一下代码来演示一遍
public class Audi extends Car {
public Audi() {
System.out.println("这是子类的构造方法");
}
}
public class Car {
public Car() {
System.out.println("这是父类的构造方法");
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
}
}
结果
我们可以看到先调用了父类的构造方法之后,才调用了子类的构造方法
下我来用一张内存图来为大家揭露this与super的关系
先上一段普通代码
public class Audi extends Car {
public void run(){
System.out.println("我是奥迪");
}
@Override
public void method(){
super.method();
System.out.println("子类方法");
}
}
public class Car {
public void method(){
System.out.println("父类方法");
}
}
public class Test {
public static void main(String[] args) {
Audi audi = new Audi();
audi.method();
audi.run();
}
}
该代码内存图
super:代表父类存储空间
this:代表子类存储空间
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空 间,便可以包含其父类的成员,
这样子就好理解多了吧,为什么会调用父类的构造方法
6注意事项
- Java只支持单继承,不支持多继承。(一个子类只能有一个父类,就像生活中一个儿子只有一个亲生的父亲)
- Java支持多层继承(继承体系)。(一个父类可以有多个子类,就像生活中一个父亲有多个子女)