Java基础——继承
来源:互联网 发布:淘宝便宜的布料店 编辑:程序博客网 时间:2024/05/16 19:14
继承是面向对象的三大特征之一,也是实现软件复用的重要手段。Java的继承具有单继承的特点,每个子类只有一个直接父类。
一、继承的特点
Java的继承通过extends关键字实现,实现继承的类被称为子类,被继承的类称为父类,有的也称为基类、超类。父类和子类的关系,是一种一般和特殊的关系。例如水果和苹果的关系。苹果继承了水果,苹果是水果的子类,则苹果是一种特殊的水果。
因为子类是一种特殊的父类,因此父类包含的范围总比子类包含的范围要大,所以可以认为父类是大类,而子类是小类。
Java里子类继承父类的语法格式如下:
修饰符 class SubClass extends SuperClass{ //类定义部分}
定义子类地方语法很简单,只需在原来类定义上增加extends SuperClass即可,即表明该子类继承了SuperClass类。
Java使用extends作为继承的关键字,extends关键字在英文中是扩展,而不是继承。这个关键字很好体现了父类与子类的关系:子类是对父类的扩展,子类是一种特殊的父类。 子类扩展了父类,将可以获得父类全部成员变量和方法,这与汉语中的继承很好的类似性。但是,Java的子类不能获得父类的构造器。
下面程序示范了子类继承父类的特点。下面是Fruit类的代码。
public class Fruit{ public double weight; public void info() { System.out.println("我是一个水果,重" + weight + "g"); }}
接下来定义该Fruit类的子类Apple,程序如下。
public class Apple extends Fruit{ public static void main(String[] args) { //创建Apple对象 Apple a = new Apple(); //Apple对象本身没有weight成员变量 //因为Apple的父类有weight成员变量 //也可以访问Apple对象的weight成员变量 a.weight = 56; //调用Apple的info方法 a.info(); }}
上面的Apple类基本是一个空类,它只包含了一个main()方法,但程序中创建了Apple对象之后,可以访问该Apple对象的weight实例变量和info()方法,这表明Apple对象也具有了weight实例变量和iinfo()方法,这就是继承的作用。
Java摒弃了C++中难以理解的多继承特征,即每个类最多只有一个直接父类。
例如,下面的代码将引起编译错误:
class SubClass extends Base1 , Base2 , Base3 {...}
有些书在介绍Java单继承时,可能会说,Java类只能有一个父类。严格来说,这种说法应该是:Java只能有一个直接父类,实际上Java类可以有无限多个间接父类。
例如:
class Fruit extends Plant{...}class Apple extends Fruit{...}
上面类的工艺中Fruit是Apple类的父类,Plant类也是Apple类的父类。区别是Fruit是Apple类的间接父类。
如果定义一个Java类时并未显式指定这个类的直接父类,则这个类默认扩展java.lang.Object类。因此,java.lang.Object类是所有类的父类,要么是其直接父类,要么是其间接父类。因此所有java对象都可调用java.lang.Object类所定义的实例方法。
从子类的角度来看,子类扩展(extends)父类:但从父类角度来看,父类派生(derive)出了子类。也就是说,扩展和派生描述的是同一个动作,只是观察角度不同而已。
二、重写父类的方法
子类扩展了父类,子类是一个特殊的父类。大部分时候,子类总是以父类为基础,额外增加新的成员变量和方法。但是有一种情况例外:子类需要重写父类的方法。
例如,鸟类都包含了飞翔方法,鸵鸟是一种特殊的鸟类,因此鸵鸟是鸟类的子类,因此它从鸟类获得飞翔的方法,但是这个飞翔的方法不适合鸵鸟,所以鸵鸟需要重写鸟类的方法。
下面程序先定义一个Bird类。
public class Bird{ //Bird类的fly()方法 public void fly() { System.out,println("我在天空中飞翔..."); }}
下面定义一个Ostrich类,这个类扩展了Bird类,重写了Bird的方法。
public class Ostrich extends Bird{ //重写Bird类fly()方法 public void fly() { System.out.println("我只能在地上奔跑..."); } public static void main(String[] args) { //创建Ostrich对象 Ostrich os = new Ostrich(); //执行Ostrich对象的fly方法,将输出"我只能在地上奔跑..." os.fly(); }}
这种子类包含与父类同名的方法的现象被称为方法重写(Override),也被称为方法覆盖。可以说子类重写了父类的方法,也可说是子类覆盖了父类的方法。
方法重写要遵守“两同两小一大”规则。
“两同”即方法名相同、形参列表相同;
“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常应比父类方法抛出的异常类更小或相等;
“一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等。
需要指出的是,覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法。
例如,下面的代码将会编译错误。
class BaseClass{ public static void test(){...}}class SubClass extends BaseClass{ public void test(){...}}
当子类覆盖了父类的方法后,子类将无法访问父类中被覆盖的方法,但可以在子类方法中调用被覆盖的方法。如果需要在子类方法中调用父类被覆盖的方法,则可以使用super(被覆盖的实例方法)或者父类名(被覆盖的实例方法)作为调用者来调用父类中被覆盖的方法。
如果父类方法具有private访问权限,则该方法对其子类是隐藏的,因此子类无法访问,也就是无法重写该方法。如果子类中也定义了一个与父类private方法具有相同的方法名、相同的形参列表、相同的返回值类型的方法,只是在子类中定义了一个新方法。
class BaseClass{ //test()方法是private访问权限,子类不可访问该方法 private void test() {...}}class SubClass extends BaseClass{ //此处并不是方法重写,可以增加static关键字 public static void test(){...}}
方法重载和方法重写在英文中分别是overload和override。
重载和重写的区别在哪呢?
其实把重载和重写放在一起比较本身没太大的意义,因为重载主要发生在同一个类的多个同名方法之间,而重写发生在子类和父类同名方法之间。当然,父类和子类方法之间也可发生重载,因为子类可以获得父类的方法,如果子类定义了一个与父类方法有相同方法名,但参数列表不同的方法,就会形成父类方法和子类方法的重载。
- Java基础—继承
- Java基础——继承
- Java基础——继承
- Java基础——继承
- Java基础——继承
- java基础—继承连接
- java—基础篇——继承
- JAVA基础——继承性
- Java基础——封装、继承、多态
- 黑马程序员——Java基础---继承
- JAVA基础 —— 继承、抽象、接口
- 黑马程序员——Java基础---继承
- 黑马程序员——Java基础--继承
- 黑马程序员——JAVA基础---继承
- 黑马程序员—Java基础—继承
- 程序员——java基础之继承
- java基础提高笔记——继承
- java基础(二)——继承
- C++第六次实验
- C++第6次实验—作业
- uisearchbar背景色
- Gradle学习系列之六——使用Java Plugin
- poj 3253 Fence Repair
- Java基础——继承
- 手把手教你写框架之ShykyAnnotations - 配置篇
- c++第6次实验——作业
- Android SQLite 的介绍和使用(二)
- Spring源码解读-Spring IoC容器初始化之资源解析
- 详解Paint的setColorFilter(ColorFilter filter)
- mybatis insert 返回主键
- Linux Pthread 总结
- [疯狂Java]基础类库:StringBuilder/StringBuffer