文档章节

Java基础进阶_day02_(类的组合,继承,this与super关键字)

S
 Sunmos
发布于 2017/05/13 00:18
字数 3539
阅读 4
收藏 0

内容摘要:

  • 类的组合关系
  • 类的继承(重点)
  • 子父类间成员关系(重点)
  • 方法的重写(重点)
  • this与super关键字(重点)

1. 类的组合关系

类与类间存在三种关系:

组合:如果自定义类型A中的属性值的类型是另一个自定义类型B时,A与B之间就是组合关系.
继承:暂未学习
代理:暂未学习
案例:

// Person和Pet是组合关系
public class Person {
     String name;
Pet pet;
}
public class Pet {
     String name;
String color;
}

2. 类的继承

概念:

把多个类中相同的成员提取出来定义到一个独立的类中,然后让这些类和独立的类产生一个关系后,都能直接使用独立类中的成员,这个关系就是继承.

格式:

class 子类名 extends 父类名 {}
extends:代表继承的关键字

好处:

提高代码的复用性;
提高了代码的维护性(修改父类中方法,所有的子类均不用修改);
继承是多态的前提.

坏处:

增强了类与类间的耦合性(开发时遵循原则:低耦合,高内聚).

特点:

Java语言只支持单继承,不支持多继承;
Java语言支持多层继承,不支持循环继承.

何时使用继承:

采用假设法,继承遵循”is a”的原则(A类是B类的一种,才能使用继承).

注意事项:

子类只能访问父类中的非私有的成员(成员变量和成员方法);
不能为获取某一个功能而去继承一个类;
子类没有继承父类的构造方法,当可以通过super()调用父类的无参构造,super(参数)调用父类的有参构造.

案例:

package com.itheima.extendsreview;
/* * 继承案例 */
public class ExtendsDemo {
    public static void main(String[] args) {
        // 创建子类对象,子类可以访问父类的非私有的成员
        Teacher t = new Teacher("张三", 16);
        t.age = 20;     // 可以访问父类非私有的成员变量
        //t.name = "李四"; // 子类不能访问父类的私有的成员变量
        t.setName("李四");    // 子类可以通过成员变量的公共的访问方法访问父类的私有成员变量
        t.showInfo();   // 子类可以访问父类的非私有的成员方法
        //t.work(); // 子类不能访问父类的非私有的成员方法
    }
}

class Person {
    private String name;
    public int age;
    public Person() {}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 公共的方法
    public void showInfo() {
        System.out.println(this.name + "..." + this.age);
    }
    // 私有的方法
    private void work() {
        System.out.println("我学习");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
class Teacher extends Person {
    // 子类不能继承父类的构造方法,构造方法是父类进行数据初始化的,
    // 如果子类继承后,子类没有对象的属性值,则有参构造会报错
    public Teacher() {}
    // 子类可以通过super关键字调用父类的构造方法,通过父类初始化属性值
    public Teacher(String name, int age) {
        super(name, age);
    }
}

3. 子父类间成员关系

类的组成:

成员变量
构造方法
成员变量

继承中成员变量关系:

1: 当子类的成员方法调用变量遵循就近原则(查询变量遵循的顺序):
本方法中局部变量–>本类中的成员变量–>父类的成员变量
2: 当子类的成员方法中局部变量,子类的成员变量,父类的成员变量三者同名时:
  该成员方法调用变量时:
  (1) 变量名:调用本方法中的局部变量;
  (2) this.变量名:调用本类中成员变量(this代表当前对象的引用);
  (3) super.变量名:调用父类中的成员变量(super代表父类存储空间的标识).

继承中构造方法的关系:

遵循规则:子类创建对象时,必须先将父类进行加载并进行初始化.
1:子类的每个构造方法的都默认调用父类的无参构造方法,即隐含super()语句,原因如下:
创建子类对象时需要先将父类进行初始化,子类才能获取父类的成员;
2:子类的构造方法可以同通过this(…)调用其他的构造方法,但至少有一个构造方法要调用父类的构造方法(父类需要进行初始化);
3:子父类构造方法执行顺序:可以看作是创建子类对象时调用子类的构造方法,子类构造方法执行过程中调用父类的构造方法(子类完成初始化前将父类进行初始化);
4:子类的构造方法的第一条有效语句必须是this(…)调用其他构造方法的语句,或者是super(…)调用父类构造方法的语句,二者只能出现一个;
5:当父类中没有空参构造时,需要通过调用父类的有参构造进行父类的初始化.

继承中成员方法的关系:

1:子类只能访问父类非私有的成员方法;
2:子类成员方法和父类非私有成员方法不同名时,这两个方法是不同的方法,子类均可访问;
3:子类成员方法和父类非私有成员方法同名时:
  (1):方法声明完全相同(返回值,参数列表):这两个方法是重写关系,子类方法将父类方法覆盖;
  (2):方法声明不完全相同[返回值不同,参数列表不同(参数个数,参数类型,类型对应的顺序)]:这两个方法是重载,子类均可访问;
4:子类成员方法和父类私有的成员方法同名时:这两个方法时各自类所独有,没有关系,子类不能访问父类的该成员方法.

案例:

package com.itheima.extendsreview;
/* * 继承体系中子父类的成员关系 */
public class ExtendsDemo2 {
    public static void main(String[] args) {
        /* * 成员变量的关系 */
        Son s = new Son();
        // A:子类的成员方法调用变量遵循就近原则
        // (查询变量定义的顺序):子类局部方法-->子类成员变量-->父类非私有成员变量
        s.show();   // 输出:age:1,age:10,age:20
        // B:当子类的成员方法中局部变量,子类的成员变量,父类的成员变量三者同名时:
        // 变量名:调用本方法中的局部变量
        // this.变量名:调用本类中成员变量(this代表当前对象的引用)
        // super.变量名:调用父类中的成员变量(super代表父类对象存储空间的标识)
        s.show2();  // 输出:age:1,age:11,age:22
        /* * 构造方法的关系 * 遵循规则:子类创建对象时,必须先将父类进行加载并进行初始化. */
        // A:子类不能继承父类的构造方法
        // 子类不能继承父类的构造方法,构造方法是父类进行数据初始化的,
        // 如果子类继承后,子类没有对象的属性值,则有参构造会报错
        // B:子类的每一个构造方法都会默认的调用父类的无参构造方法
        Son ss = new Son(); // 输出:我是父类的空参构造,我是子类的空参构造
        // C:子类的构造方法可以同通过this(...)调用子类其他的构造方法,
        // 但至少有一个构造方法要调用父类的构造方法(父类需要进行初始化);
        // D:子类的构造方法的第一条有效语句必须是this(...)调用其他构造方法的语句,
        // 或者是super(...)调用父类构造方法的语句,二者只能出现一个;
        // E:当父类中没有空参构造时,子类需要显示的调用父类的有参构造进行父类的初始化.
        /* * 成员方法的关系: */
        // A:子类只能访问父类非私有的成员方法;
        // B:子类成员方法和父类非私有成员方法不同名时,这两个方法是不同的方法,子类均可访问;
        // C:子类成员方法和父类非私有成员方法同名时:
        // 方法声明完全相同(返回值,参数列表):这两个方法是重写关系,子类方法将父类方法覆盖;
        ss.show(); // 输出:age:1,age:10,age:20
        // 方法声明不完全相同[返回值不同,参数列表不同(参数个数,参数类型,类型对应的顺序)]:这两个方法是重载,子类均可访问;
        ss.show3(); // 输出:你好
        ss.show3("张三"); // 输出:name:张三
        // D:子类成员方法和父类私有的成员方法同名时:这两个方法时各自类所独有,没有关系,子类不能访问父类的该成员方法.
        // ss.work(); // 不能访问,私有的成员方法只能在本类中访问,测试类中不能访问
    }
}
class Father {
    private String name;
    public int age = 22;
    public int age2 = 20;
    public Father() {
        System.out.println("我是父类的空参构造");
    }
    public Father(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("我是父类的有参构造");
    }
    // 公共的方法
    public void showInfo() {
        System.out.println(this.name + "..." + this.age);
    }
    public void show() {
        System.out.println(this.name + "..." + this.age);
    }
    public void show3() {
        System.out.println("你好");
    }
    // 私有的方法
    private void work() {
        System.out.println("Father学习");
    }
}
class Son extends Father {
    public int age = 11;
    public int age1 = 10;
    public Son() {
        System.out.println("我是子类的空参构造");
    }
    public Son(int age) {
        this.age = age;
        System.out.println("我是子类的空参构造");
    }

    public void show() {
        int age = 1;
        System.out.println("age:"+age);
        System.out.println("age:"+age1);
        System.out.println("age:"+age2);
    }
    public void show2() {
        int age = 1;
        System.out.println("age:"+age);
        System.out.println("age:"+this.age);
        System.out.println("age:"+super.age);
    }
    public void show3(String name) {
        System.out.println("name:"+name);
    }
    // 私有的方法
    private void work() {
        System.out.println("Son学习");
    }
}

4. 方法的重写

概念:

子父类中出现了声明完全相同(方法名,返回值,参数列表)的方法,则称为子类成员方法重写(覆盖)了父类成员的方法.

特点:

1:方法重写的前提是存在继承关系的类;
2:子类重写父类的方法的修饰权限不能小于父类该方法的权限(public > 默认);
3:父类中私有成员方法不能被重写;
4:重写的方法一般加上@Override注解,该注解表示该方法必须是重写父类的方法,否则会报错.

作用:

1:可以在父类成员方法的功能基础上,增加自身的处理逻辑,增强父类该方法的功能(需要子类在重写该方法时首先调用父类的该方法);
2:覆盖父类该方法的所有逻辑,重新定义子类的处理逻辑,将父类的功能全部舍弃.

方法的重写与重载的区别:

1:重写(override):在两个存在继承关系的类中,方法声明完全相同;
2:重载(overload):在同一个类中,方法名相同,参数列表不同(参数个数,参数类型,类型对应的顺序),与返回值无关.

案例:

package com.itheima.extendsreview;
/* * 方法重写案例 */
public class MethodOverrideDemo {
    public static void main(String[] args) {
        // A:可以在父类成员方法的功能基础上,增加自身的处理逻辑,增强父类该方法的功能(需要子类在重写该方法时首先调用父类的该方法);
        Cat c = new Cat();
        c.show1();  // 输出:Animal show1,Cat show1
        // B:覆盖父类该方法的所有逻辑,重新定义子类的处理逻辑,将父类的功能全部舍弃.
        c.show2();  // 输出:Cat show2
    }
}
class Animal {
    public void show1() {
        System.out.println("Animal show1");
    }
    public void show2() {
        System.out.println("Animal show2");
    }
    public final void show3() {
        System.out.println("Animal show3");
    }
}
class Cat extends Animal {
    // 报错,子类重写父类的方法的修饰权限不能小于父类该方法的权限(public > 默认);
    /*void show1() { System.out.println("Cat show1"); }*/
    public void show1() {
        super.show1();
        System.out.println("Cat show1");
    }
    public void show2() {
        System.out.println("Cat show2");
    }
    // 报错,因为父类的show3()方法是final修饰,不能被重写
    /*public final void show3() { System.out.println("Cat show3"); }*/
}

5. this与super关键字

this关键字:

是代表当前对象的引用;

super关键字:

代表父类存储空间在子类对象中标识,相当于对象的引用,但不是对象的引用;

注意事项:

子类构造方法中通过super调用父类的构造方法,只是表示子类创建对象完成前需要对父类进行初始化(表象),本质是在加载子类.class文件前先加载父类的.class文件,并且只是在子类对象空间(使用this标识)中为父类开辟了一块存储空间,这块空间使用super进行标识.

this与super的区别:

1: this是当前对象的引用,super只是父类存储空间的标识,在子类中调用super只是为父类初始化,不会创建父类对象,父类初始化的空间是在子类对象存储空间内;
2:访问成员变量:
  this.成员变量–>代表访问本类的成员变量
  super.成员变量–>代表访问父类非私有的成员变量
3:访问构造方法:
  this(…)–>代表访问本类的其他的构造方法
  super(…)–>代表访问父类的构造方法
4:访问成员方法:
  this.成员方法–>代表访问本类的成员方法
  super.成员方法–>代表访问父类非私有的成员方法

案例:

package com.itheima.extendsreview;
/* * this和super关键字的案例 */
public class Z extends X {
    Y y = new Y();
    public Z() {
        super();
        System.out.print("Z");
    }
    // 主方法
    public static void main(String[] args) {
        new Z(); // 输出结果为:YXYZ
        // 结果分析:类的初始化是分层初始化的
        // 1.new Z()是创建Z的对象,创建Z对象前先加载父类X
        // 2.X类中定义了Y b = new Y(),则在加载X前,先加载类Y
        // 3.Y类中初始化时,调用无参构造方法,打印了"Y",Y类初始化完后返回到X类中
        // 4.X中的构造方法执行,打印了"X",X类初始化完后返回到Z类中
        // 5.Z类中定义Y y = new Y(),则进行Y类的初始化,打印"Y",然后执行Z类的构造,打印"Z"
    }
}
class X {
    Y b = new Y();
    public X() {
        System.out.print("X");
    }
}

class Y {
    public Y() {
        System.out.print("Y");
    }
}

本文转载自:http://blog.csdn.net/l631106040120/article/details/65469637

共有 人打赏支持
S
粉丝 0
博文 34
码字总数 0
作品 0
成都
Java基础笔记 -------------面向对象上(三大特性)

面向对象三个特性:继承(Inheritence)、封装(Encapsulation)、多态(Polymorphism). 1、封装(Encapsulation): 类包含了数据与方法,将数据与方法放在一个类中就构成了封装(一般来说,...

查封炉台
2014/04/21
0
0
Java编程学习:继承的概念及方法

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰
05/30
0
0
大数据开发培训:0基础学习Java编程语言有哪些知识点?

Java 技术通用、高效、具有平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网等,学习Java首先要知道学习知识点有哪些。在这就用加米谷大数据培训...

加米谷大数据
07/25
0
0
JavaScript 中的继承:ES3、ES5 和 ES6

选择一种继承方式 JavaScript 是一门动态语言,动态意味着高灵活性,而这尤其可以体现在继承上面。JavaScript 中的继承有很多种实现方式,可以分成下面四类: Mixin 模式,即属性混入,从一个...

天方夜
07/04
0
0
Java 面试题:编译时与运行时

Q.下面的代码片段中,行A和行B所标识的代码有什么区别呢? public class ConstantFolding { static final int number1 = 5; static final int number2 = 6; static int number3 = 5; static ......

BravoZu
2014/02/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSX | SafariBookmarksSyncAgent意外退出解决方法

1. 启动系统, 按住⌘-R不松手2. 在实用工具(Utilities)下打开终端,输入csrutil disable, 然后回车; 你就看到提示系统完整性保护(SIP: System Integrity Protection)已禁用3. 输入reboot回车...

云迹
今天
3
0
面向对象类之间的关系

面向对象类之间的关系:is-a、has-a、use-a is-a关系也叫继承或泛化,比如大雁和鸟类之间的关系就是继承。 has-a关系称为关联关系,例如企鹅在气候寒冷的地方生活,“企鹅”和“气候”就是关...

gackey
今天
4
0
读书(附电子书)|小狗钱钱之白色的拉布拉多

关注公众号,在公众号中回复“小狗钱钱”可免费获得电子书。 一、背景 之前写了一篇文章 《小狗钱钱》 理财小白应该读的一本书,那时候我才看那本书,现在看了一大半了,发现这本书确实不错,...

tiankonguse
今天
4
0
Permissions 0777 for ‘***’ are too open

异常显示: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ......

李玉长
今天
5
0
区块链10年了,还未落地,它失败了吗?

导读 几乎每个人,甚至是对通证持怀疑态度的人,都对区块链的技术有积极的看法,因为它有可能改变世界。然而,区块链技术问世已经10年了,我们仍然没有真正的用上区块链技术。 几乎每个人,甚...

问题终结者
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部