路漫漫其修远兮,吾将上下而求索。
--屈原《离骚》
一、继承的概念
继承是所有OOP语言和Java语言中不可缺少的组成部分。当创建一个类时,总是在继承,因此,除非已明确指出要从其他类中继承,否则就是在隐式的从Java的标准根类Object进行继承。组合的语法比较平实,但是继承使用的是一种特殊的语法。在继承过程中,先要声明“新类与旧类相似”。这种声明是通过在类主体的左边花括号之前,书写后面紧随基类名称的关键字extends而实现。当这么做时,会自动得到基类中所有的域和方法。
继承的好处:
提高的代码的复用性
多个类相同的成员可以放在同一个类中
提高了代码的维护性
如果功能的代码需要修改,修改一处即可
让类与类之间产生了关系,是多态的前提
其实这也是继承的一个弊端:类的耦合性很强
//耦合性 - 内聚:我们写程序要专注于高内聚,低耦合。
二、extends关键字
语句定义格式
class A extends B{}
A:子类,派生类
B:父类,基类,超类
三、继承使用注意事项
- 类与类之间只能单继承,不能多继承。
- 可以多层继承,形成继承体系。
- 子类只能继承父类中非私有的成员。
- 子类无法继承父类的构造方法,但是可以使用。
- 子类无法继承父类中的静态成员,但是可以使用
- 想要初始化子类,必须先初始化其父类
/*
使用继承的注意事项:
1、子类无法继承父类中所有私有的成员(成员变量、成员方法)
2、子类无法继承父类中的构造方法
3、不要因为有部分功能重复就立刻使用继承
class A{
fun1();
fun2();
fun3();
}
class B{
fun2();
fun5();
fun&();
}
-----------------------
class Fu{
fun2();
}
class A extends Fu{
fun1();
fun3();
}
class B extends Fu{
fun5();
fun7();
}
4、什么时候用继承呢?
类和类之间的关系满足英语语法上的“is a” 举例:华为是手机,苹果是手机,小米是手机,
则手机就可以被定义成父类
*/
class Fu{
int a = 10;
private int b = 20;
public void show1(){
System.out.println("好好学习,天天向上!");
}
private void show2(){
System.out.println("天天上香,求佛拜神");
}
}
class Zi extends Fu{
// a=10;
public void fun1(){
System.out.println(a);
// System.out.println(b); //子类无法继承父类中的私有的成员变量
}
}
public class Ex1 {
public static void main(String[] args) {
Zi z = new Zi();
System.out.println(z.a);
z.fun1();
z.show1(); //使用继承自父类中的非私有方法
//z.show2(); //子类无法继承父类中的私有方法
}
}
继承与成员变量的关系:
1.怎么寻找?
子类方法中使用变量的规则是:(就近原则)
1)先在方法内部寻找,若找到就直接使用
2)方法内部找不到,就去当前类的成员变量的位置中去寻找,若找到就直接使用
3)若当前类的成员变量的位置上找不到,去父类的成员变量位置寻找,若找到就直接使用
4)上面三个位置都没有找到要使用的变量的话,就会产生报错!
2.我就是想在子类有和父类一样的变量名的情况下,使用父类中的变量。Java提供了另一个关键字:super代表的是直接父类的引用,无法调用父类的父类,可以通过super关键字使用父类中非私有的成员。
class GFu{
}
class Fu1 extends GFu {
int a = 10;
}
class Zi1 extends Fu1{
int a = 30;
public void fun1(){
int a = 20;
System.out.println(a);
//使用父类的a
// System.out.println(Fu.a); // a是静态的时候,才可以直接通过类名的方式进行调用
// Fu fu = new Fu();
// System.out.println(fu.a); //按照之前的知识实现,就可以通过对象来访问非私有的成员
System.out.println(this.a); // 使用当前对象的成员变量a
System.out.println(super.a); // 使用直接父类Fu中的成员变量a
}
}
public class Ex2 {
public static void main(String[] args) {
Zi1 z = new Zi1();
System.out.println(z.a);
z.fun1();
}
}
Java中的初始化顺序
在Java中,类的加载顺序遵循一定的规则,基本上遵循“顺序”和“层次”。以下是加载顺序的概要:
- 父类静态变量和静态代码块(按在代码中出现的顺序)。
- 子类静态变量和静态代码块(按在代码中出现的顺序)。
- 父类实例变量和代码块(按在代码中出现的顺序)。
- 父类构造函数。
- 子类实例变量和代码块(按在代码中出现的顺序)。
- 子类构造函数。
类的加载的顺序:先加载父类,再加载子类的
类的初始化的顺序:先初始化父类,再初始化子类的
在有父子关系中的两个类中,先加载父类中的静态成员变量以及静态代码块,再加载子类中的静态成员以及静态代码块,父类的成员变量先进行初始化,然后再
初始化父类的构造代码块,之后父类的构造方法,然后是子类的成员变量先进行初始化,然后再初始化子类的构造代码块,之后子类的构造方法。
四、super关键字
1、super关键字的概述
如果程序中的每一个类均含有默认的构造器,即这些构造器都不带参数。编译器可以轻松地调用他们是因为不必考虑要传递什么样的参数的问题。但是,如果没有默认的基类构造器,或者想调用一个带参数的基类构造器,就必须使用关键字super显示地调用基类构造器的语句,并且配以适当的参数列表。
2、使用方法
- 成员变量:super.成员变量
- 构造方法:super(...)
- 成员方法:super.父类方法名(...)
3、注意事项
1、针对在子类中使用super调用父类的构造方法的时候,子类的构造方法默认第一句话是super()
2、若父类中没有无参构造方法,可以使用super显示地调用父类的有参构方法进行初始化
class Game{
Game (int i){
System.out.println("Game constructor");
}
}
class BoardGame extends Game{
BoardGame(int i){
super(i);
System.out.println("BoardGame constructor");
}
}
public class Chess extends BoardGame {
Chess () {
super(11);
System.out.println("Chess constructor");
}
public static void main(String[] args) {
Chess x = new Chess();
}
}
/*
output:
Game constructor
BoardGame constructor
Chess constructor
*/
五、重写
1、重写的概念
重写(Override)是指子类定义了一个与其父类中具有相同名称、参数列表和返回类型的方法,并且子类方法的实现覆盖了父类方法的实现。即外壳不变,将内容重写!
好处:重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。这样,再使用子类对象调用该方法时,将执行子类中的方法而不是父类中的方法。
2、继承和成员的关系
- 寻找规则:先在本类中寻找,若找到就使用;若本类中没有对应方法,就使用继承父类中的方法,若还是没有,那就报错。
- Java中所有的类都有一个共同的父类:Object。
- 如果子类中的方法的返回值类型,方法名,参数列表都与父类中的一样,这样的现象叫做覆盖(重写),建议使用@Override来表示。
3、面试题
重载和重写的区别(Overload和Override的区别?)
Overload重载:发生在同一个类中的,方法名一样,参数列表部一样,与返回值无关。
Override重写:发生在继承关系中的,返回值类型,方法名,参数列表都要一样,只是方法体现不一样。
4、重写的注意事项
- 重写后的方法,权限不能比父类中的方法的权限要低,一般情况下,重写的方法权限与父类的方法保持一致。
- 父类静态方法,子类无法重写,静态的成员方法随着类。
六、final关键字
1、概述
根据上下文环境,Java的关键字final的含义存在着细微的差别,但是通常可以理解为它是指“这是无法改变的”。不想做出改变的理由可能出于两种情况:设计和效率。由于这两个原因相差十分巨大,故关键字final有可能被误用。
2、修饰
final可以用于数据、方法和类这三种情况。
- 类:类将不可以被继承
- 变量:变量变成常量,值不能被修改
- 成员方法:子类无法冲重写,但是可以使用
常量:
- 字面值常量:
- 自定义常量:被final所修饰的变量
class Fu4{ final int a = 10; } class Zi4 extends Fu4{ public void fun1(){ // a = 100; // 被final修饰变量,不能修改其值。 System.out.println(a); } } public class FinalDemo { public static void main(String[] args) { Zi4 zi4 = new Zi4(); zi4.fun1(); } }
3、final和private关键字
类中所有的private方法都隐型地指定为final的。由于无法取用private方法,所以也就无法覆盖它。所以对private方法添加final修饰词,但是并不能给该方法增加任何额外的意义。(编译器将不会报错!!!)
4、初始化时机
被final修饰的变量,在构造方法完毕之前赋值即可。
5、忠告
在设计类时,将方法指名是final的,可以说是明智的。你可能会觉得,没人想要覆盖你的方法。有时这样是对的。
但是请留意你设置的假设。要预见类是如何被复用的一般是比较困难的,特别是对于一个通用类而言更是如此。如果将一个方法指定为final,可能会妨碍其他程序员在项目中调用你的类,而这仅仅因为你没有想到它会以那样的方式被调用。同时使用final可能会降低程序的运行效率,在此不做解释,请谨慎使用final。
七、练习
-- 1、编写应用程序,创建类的对象,分别设置圆的半径、圆柱体的高,计算并分别显示 圆半径、圆面积、圆周长,圆柱体的体积。(7 分)
提示:(1)编写一个圆类 Circle,该类拥有:
1)一个成员变量,radius(私有,浮点型);//存放圆的半径;
2)两个构造方法
Circle() //将半径设为 0
Circle(double r ) //创建 Circle 对象时将半径初始化为 r
3)三个成员方法
double getArea() //获取圆的面积double getPerimeter() //获取圆的周长
void show() //将圆的关径、周长、面积输出到屏幕
(2)编写一个圆柱体类 Cylinder,它继承于上面的 Circle 类。还拥有:
1)一个成员变量,double hight (私有,浮点型); //圆柱体的高;
2)构造方法
//创建 Cylinder 对象时将半径初始化为 r,高度初始化为 h Cylinder(double r,double h)
3)成员方法
double getVolume() //获取圆柱体的体积
void showVolume() //将圆柱体的体积输出到屏幕
-- 2、请使用面向对象的思想,设计自定义类,描述出租车和家用轿车的信息。 设定
1)出租车类:
属性包括:车型,车牌,所属出租公司;方法包括:启动,停止
2)家用轿车类:
属性包括:车型,车牌,车主姓名;方法包括:启动,停止
要求
1)分析出租车和家用轿车的公共成员,提取出父类—汽车类
2)利用继承机制,实现出租车类和家用轿车类
3)编写测试类,分别测试汽车类,出租车类和家用轿车类对象的相关方法
4)定义名为 car 的包存放汽车类,出租车类,家用轿车类和测试类运行效果
-- 3、某公司要开发新游戏,请用面向对象的思想,设计游戏中的蛇怪和蜈蚣精 设定
1)蛇怪类:
属性包括:怪物名字,生命值,攻击力
方法包括:攻击,移动(曲线移动),补血(当生命值<10 时,可以补加 20 生命值)
2)蜈蚣精类:
属性包括:怪物名字,生命值,攻击力方法包括:攻击,移动(飞行移动) 要求
1)分析蛇怪和蜈蚣精的公共成员,提取出父类—怪物类
2)利用继承机制,实现蛇怪类和蜈蚣精类
3)攻击方法,描述攻击状态。内容包括怪物名字,生命值,攻击力
4)编写测试类,分别测试蛇怪和蜈蚣精的对象及相关方法
5)定义名为 mon 的包存怪物类,蛇怪类,蜈蚣精类和测试类运行效果
-- 4、请用面向对象的思想,设计自定义类描述演员和运动员的信息 设定
1)演员类:属性包括:姓名,年龄,性别,毕业院校,代表作 方法包括:自我介绍
2)运动员类:属性包括:姓名,年龄,性别,运动项目,历史最好成绩 方法包括:自我介始
要求
3)分析演员和运动员的公共成员,提取出父类—人类
4)利用继承机制,实现演员类和运动员类
5)编写测试类,分别测试人类,演员类和运动员类对象及相关方法
定义名为 act 的包存人类,演员类,运动员类和测试类运行效果
八、答案
1、
这题的类型选错了HomeWork01应该使用包,写的时候没有看到,后面是对的,不想改了。将就看看吧,谢谢理解!!!
package day08;
import java.lang.Math;
import static java.lang.Math.pow;
class Circle {
private double radius = 0;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public Circle() {
}
public Circle(double radius) {
this.radius = radius;
}
public double getArea() {//获取圆的面积
return Math.PI * pow(radius, 2);
}
public double getPerimeter() {//获取圆的周长
return 2 * Math.PI * radius;
}
public void show() {//将圆的半径、周长、面积输入到屏幕
System.out.println("半径:" + radius);
System.out.println("面积:" + getArea());
System.out.println("周长:" + getPerimeter());
}
}
class Cylinder extends Circle{
private double high;
public Cylinder() {
}
public Cylinder(double radius, double high) {
super(radius);
this.high = high;
}
public double getVolume(){
return super.getArea()*high;
}
public void showVolume(){
System.out.println("圆柱体的体积输出:"+getVolume());
}
}
public class HomeWork01 {
public static void main(String[] args) {
Circle c1 = new Circle(2.0);
c1.show();
Cylinder c2 = new Cylinder(3.0,5);
c2.showVolume();
}
}
2、按自上而下的顺序观看
package HomeWork02_car;
public class Car {
private String carKind;
private String carCard;
public Car() {
}
public Car(String carKind, String carCard) {
this.carKind = carKind;
this.carCard = carCard;
}
public String getCarKind() {
return carKind;
}
public void setCarKind(String carKind) {
this.carKind = carKind;
}
public String getCarCard() {
return carCard;
}
public void setCarCard(String carCard) {
this.carCard = carCard;
}
public void start(){
System.out.println("我是车,我启动");
}
public void end(){
System.out.println("我是车,我停止");
}
public void show(){
start();
end();
}
}
package HomeWork02_car;
public class HomeCar extends Car{
private String name;
public HomeCar() {
}
public HomeCar(String carKind, String carCard, String name) {
super(carKind, carCard);
this.name = name;
}
public void start(){
System.out.println("我是"+this.name+",我的汽车我做主");
}
public void end(){
System.out.println("目的地到了,我们去玩吧");
}
public void show(){
this.start();
this.end();
}
}
package HomeWork02_car;
public class Test {
public static void main(String[] args) {
Car c = new Car();
c.show();
System.out.println("--------------------------");
HomeCar hc = new HomeCar("五菱宏光","京A312","武大郎");
hc.show();
System.out.println("--------------------------");
WorkCar wc = new WorkCar("桑塔纳","京A123","景顺出租车公司");
wc.show();
}
}
package HomeWork02_car;
public class WorkCar extends Car {
private String company_name;
public WorkCar() {
}
public WorkCar(String carKind, String carCard, String company_name) {
super(carKind, carCard);
this.company_name = company_name;
}
public void start(){
System.out.println("乘客您好");
System.out.println("我是"+company_name+",我的车牌是"+super.getCarCard()+",您要去哪里?");
}
public void end(){
System.out.println("您的目的地已经到了,请您付费下车,欢迎再次乘坐");
}
public void show(){
this.start();
this.end();
}
}
3、按自上而下顺观看
package HomeWork03_mon;
public class centipede extends mon{
public centipede() {
}
public centipede(String name, int HP, int AD) {
super(name, HP, AD);
}
public void move() {
System.out.println("我是蜈蚣精,御风飞行");
}
public void show(){
super.show();
move();
}
}
package HomeWork03_mon;
public class mon {
private String name;
private int HP;
private int AD;
public mon() {
}
public mon(String name, int HP, int AD) {
this.name = name;
this.HP = HP;
this.AD = AD;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getAD() {
return AD;
}
public void setAD(int AD) {
this.AD = AD;
}
public void show(){
System.out.println(name+"展开攻击");
System.out.println("当前生命值是:"+HP);
System.out.println("攻击力是:"+AD);
}
}
package HomeWork03_mon;
public class snake extends mon{
public snake() {
}
public snake(String name, int HP, int AD) {
super(name, HP, AD);
}
public void move(){
System.out.println("我是蛇怪,我走S型路线");
}
public void Heal_HP(){
if (super.getHP() < 10){
System.out.println("实施大补血术。。。。。。。,当前生命值是:"+(super.getHP()+20));
}
}
public void show(){
super.show();
Heal_HP();
move();
}
}
package HomeWork03_mon;
public class Test {
public static void main(String[] args) {
snake sn = new snake("蛇精",5,20);
centipede ce = new centipede("蜈蚣精",60,15);
sn.show();
System.out.println("--------------------------");
ce.show();
}
}
4、按自上而下的顺序观看
package HomeWork04_act;
public class act_human extends human{
private String school;
private String actwork;
public act_human() {
}
public act_human(String name, int age, String sex, String school, String actwork) {
super(name, age, sex);
this.school = school;
this.actwork = actwork;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getActwork() {
return actwork;
}
public void setActwork(String actwork) {
this.actwork = actwork;
}
public void jieshao(){
System.out.println("大家好!我是"+getName());
System.out.println("今年"+getAge());
System.out.println("我毕业于:"+school);
System.out.println("代表作有:"+actwork);
}
}
package com.shujia.day08.HomeWork04_act;
public class guy_human extends human{
private String sport;
private String record;
public guy_human() {
}
public guy_human(String name, int age, String sex, String sport, String record) {
super(name, age, sex);
this.sport = sport;
this.record = record;
}
public String getSport() {
return sport;
}
public void setSport(String sport) {
this.sport = sport;
}
public String getRecord() {
return record;
}
public void setRecord(String record) {
this.record = record;
}
public void jieshao(){
System.out.println("大家好!我是"+getName());
System.out.println("今年"+getAge());
System.out.println("我最擅长的运动"+sport);
System.out.println("历史最好成绩是"+record);
}
}
package HomeWork04_act;
public class human {
private String name;
private int age;
private String sex;
public human() {
}
public human(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
static {//在程序最开始时加载一次,以后不加载
System.out.println("我就是一个普通的老百姓");
}
}
package HomeWork04_act;
public class Test {
public static void main(String[] args) {
act_human a = new act_human("章依",27,"女","北京电影学院","《寄往天国的家书》");
a.jieshao();
System.out.println("===========================");
guy_human g = new guy_human("刘小翔",23,"男","200米短跑","22秒30");
g.jieshao();
}
}