面向对象基础9(继承与继承语法)

面向对象基础9(继承)

封装、继承、多态是面向对象的三大特征

继承的理解

苹果(类)继承了水果(类)

老虎(类)继承了动物(类)

  • Java的继承是类与类之间的关系

  • 是一种由一般到特殊的关系(与现实中的辈分没有关系,所以子类和父类名字并不准确)

——小类(子类)是一种特殊的父类(大类)

子类的实例完全可当做父类的实例来使用

别称

父类(超类、基类、大类);子类(派生类、小类)

继承的语法

修饰符 class 类名 extends 父类

{代码块}

说明:

Java是单继承的,所以,一个子类只能继承一个父类

若不显示继承父类,Java会默认继承Object

——一切皆Object!

举例:

public class A {
}
class B extends A{

}
class C extends B{
    
}
//C的直接父类是B;Object、A是C的间接父类(我附庸的附庸不是我的附庸...)
//A的直接子类是B,间接子类是C

继承的作用:

子类继承父类,就可以直接使用父类的方法成员变量

举例1:

public class Bird {
    public void fly(){
        System.out.println("Birds Flying");
    }
}
class Sparrow extends Bird{

}
//此处Sparrow类继承Bird类,Sparrow类并没有写任何方法但继承了Bird类的方法
public class SparrowTest {
    public static void main(String[] args) {
        Sparrow sp=new Sparrow();
        sp.fly();
    }
}
/*
Birds Flying
*/

继承的优点是可以实现代码的复用

方法重写

存在意义

当子类发现父类的方法不适合自己的时候,就需要重写方法

规则

两同两小一大:

两同:方法名相同、形参列表相同;

两小:返回值类型相同或者更小,声明抛出的异常相同或者更小;

一大:访问权限相同或者更大

举例2:

public class Ostrich extends Bird{
    //重写fly方法
    @Override
    public void fly(){
        System.out.println("can not fly");
    }
}
public class OstrichTest {
    public static void main(String[] args) {
        Ostrich A=new Ostrich();
        A.fly();
    }
}
/*
can not fly
*/

此时原有的fly方法被重写

注解@Override——用于报错,要求被修饰的方法必须重写父类方法,否则就报错(方法拼写错误);

Super关键字

this引用很相像,super可以用于限定访问父类的实例变量和实例方法。

super.父类的实例变量

super.父类的实例方法(参数)

例3:

class Base {
    int age=2;
}
class Sub extends Base{
    int age =20;
    public void test(){
        int age=200;
        System.out.println(age);
        System.out.println(this.age);//调用该类中的成员变量
        System.out.println(super.age);//调用父类中的成员变量
        public void names(String name)
    {
        System.out.println("执行父类"+name);
    }
    }
}
public class SubTest {
    public static void main(String[] args) {
        Sub A=new Sub();
        A.test();
    }
}
/*
200
20
2
*/

例3改:

class Base {
    int age=2;
}
class Sub extends Base{
    public void test(){
        System.out.println(age);
        System.out.println(this.age);
        System.out.println(super.age);
    }//此处删除了原有的局部变量与子类中的成员变量
}
public class SubTest {
    public static void main(String[] args) {
        Sub A=new Sub();
        A.test();
    }
}
/*
2
2
2
*/

从上面两个例子可以看出:

变量的调用遵循就近原则,输出的age变量优先调用所属方法的局部变量,若局部变量不存在,其次考虑所属类的实例变量(此处是子类),最后考虑其父类的实例变量。

thissuper关键字再次就是为了打破就近原则,调用所需要的变量。

class Base {
    public void names(String name)
    {
        System.out.println("执行父类"+name);
    }
}
class Sub extends Base{
    public void names(String name)
    {
        System.out.println("执行子类"+name);
    }
    public void test(){
        names("Java");
        /*
        此处等同于this.names("Java");
        等同于Base.names("Java");
        类方法需要类来调用,默认添加类名
        */
        super.names("Java");
    }
}
public class SubTest {
    public static void main(String[] args) {
        Sub A=new Sub();
        A.test();
    }
}
/*
执行子类Java
执行父类Java
*/

此时带有super关键子的names方法会打破就近原则,执行父类的原有方法。

子类调用父类的构造器

子类的构造器一定要调用父类的构造器一次(有且仅有一次)

  1. 如果子类构造器没有显示调用父类构造器,系统会在子类构造器的第一行自动调用父类无参数的构造器;

  2. 子类构造器的第一行显示使用super调用父类构造器:super()

    super和this关键字不顾能出现在同一语句

例5:

package Super关键字;
class Fruit{
    private double weight;
    public Fruit(double weight)
    {
        this.weight=weight;
    }
}
public class Apple extends Fruit {
    public Apple() {
        super(2.2);//常识调用父类Fruit的double构造器
    }
}

备注:如果父类没有无参构造器——则子类构造器必须显示调用(super调用,如上例)父类的构造器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值