java学习(四)(继承与多态)

继承与多态

类的继承

被继承的类称为父类或超类,继承得到的类称为子类或派生类。

public class SubClass extends SuperClass{
​
//类体定义
​
}

几点说明

  • 子类继承父类中非private的成员变量和成员方法。

  • 父类中定义的private成员变量和方法不能被子类继承,因此在子类中不能直接使用。如果父类中定义了公共的访问方法和修改方法,子类可以通过这些方法访问或修改它们。

  • final修饰符修饰的类不能被继承。

  • 定义类时若缺省extends关键字,则所定义的类为java.lang.Object类的直接子类。

  • java仅支持单重继承,即一个类至多只有一个直接父类。(在java中可以通过接口实现其他语言的多重继承)

方法覆盖

在子类中定义与父类中的名字、参数列表、返回值类型都相同的方法,这时子类的方法就叫作覆盖或重写了父类的方法。

@Override
public String toString(){
    return "姓名:"+name;
}

@Override注解表示其后的方法必须是覆盖父类的一个方法,可避免编写错误。

两点注意

  • private方法不能覆盖

  • 父类中的static方法可以被继承,但不能被覆盖。如果子类中定义了与父类中的static方法完全一样的方法,那么父类中的方法被隐藏。父类中被隐藏的static方法仍然可以使用“类名.方法名()”形式调用。

  • final修饰的方法不能被子类覆盖,否则会发生编译错误。

方法重载与方法覆盖

方法重载是在一个类中定义多个名称相同但参数不同的方法。方法覆盖实在子类中为父类中的同名方法提供一个不同的实现。

super关键字

(1)在子类中调用父类中被覆盖的方法

super.methodName([paramlist])

(2)在子类中调用父类的构造方法

super([paramlist])

不能用super调用间接父类的构造方法,如super.super()是不合法的。

在任何情况下,创建一个类的实例时,将会沿着继承链调用所有父类的构造方法。

//定义父类
public class Vehicle{
    public Vehicle(){
        System.out.println("创建Vehicle对象");
    }
}
//子类
public class Bicycle extends Vehicle{
    public Bycicle(){
        System.out.println("创建Bycicle对象");
    }
    public static void main(String[] args){
        Bycicle mybycicle = new Bycicle;
    }
} 
//运行结果
//创建Vehicle对象
//创建Bycicle对象

(3)在子类中访问父类中被隐藏的成员变量

super.variableName

methodName:父类中被覆盖的方法名

paramlist:方法传递的参数

variableName:父类中被隐藏的变量名

封装性与访问修饰符
实现封装的两种方式:

(1)通过包实现封装性。包是Java语言最大的封装单位。

(2)通过类或类的成员访问权限实现封装性。

类成员的访问权限

(1)private:私有成员,只能被这个类本身访问,外界不能访问。

(2)缺省访问修饰符:一般称为包可访问的。可以被该类本身和同一个包中的类访问,其他包中的类不能访问这些成员。

(3)protected:保护成员。可被这个类本身、同一个包中的类以及该类的子类(包括同一个包以及不同包中的子类)访问。

(4)public:公共成员。可以被任何其他的类访问。

抽象类(abstract)
public abstract class Shape{
    String name;
    public Shape(){} //抽象类可以定义构造方法
    public Shape(String name){
        this.name=name;
    }
    public abstract double getArea(); //定义抽象方法
}
  • 抽象方法:只有方法的声明,没有方法的实现。作用为所有子类提供一个统一的接口。

  • 包含抽象方法的类必须定义为抽象类。抽象类中可以定义非抽象的方法。

  • 抽象类中可以定义构造方法,这些构造方法可以在子类中调用。

  • 抽象类不能被实例化,即不能生成抽象类的对象。

Shape sh = new Shape();//发生编译错误,抽象类不能实例化
  • 抽象类的子类还可以是抽象类,只有非抽象的子类才能使用new创建该类的对象。

  • 抽象类必须被子类继承,才能实例化。

对象转换

(子类对象和父类对象在一定条件下可以相互转换)

自动转换(向上转换)

子类是父类的特殊化,每个子类的实例也都是它父类的实例。

子类对象可以作为父类对象使用,即子类对象可以自动转换为父类对象,将子类型的引用赋值给父类型的引用。

parent = child; //子类对象自动转换为父类对象,parent为父类型引用,child为子类型引用
强制转换(向下转换)

通过()。

Employee emp = new Employee("lihua");
Person p = emp;
emp = (Employee)p; //emp子类对象,p父类对象 

父类对象转换为子类对象,必须要求父类对象是用子类构造方法生成的。

Person p = new Person();
Employee emp = (Employee)p;//不能强制转换

当将一个子类型引用转换为一个父类型引用时,使用该引用可以调用父类型中定义的方法,但看不到子类型中定义的方法。

instanceof运算符

测试一个实例是否是某种类型的实例。

variable instanceof TypeName

Fruit fruit = new Apple();
//Fruit:父类 Apple:子类
//表达式fruit instanceof Fruit的结果为true.
多态与动态绑定

(1)静态多态:也叫编译时多态,是通过方法重载实现的。

(2)动态多态:也叫运行时多态,是通过方法覆盖实现的。

方法绑定:将方法调用与方法体关联起来。

动态绑定:在程序运行时根据对象的类型进行绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值