this关键字的使用:
定义:指向当前对象的一个代名词。
当前对象:谁在调用这个方法(这个方法在为谁服务),谁就是我的当前对象!
this关键字的特殊用法:还可以在对象方法中指代调用其他的对象方法:在对象方法当中通过this.的方式调用其他对象方法、对象属性的时候,this.可以不写,默认就有
注意:在静态结构中不允许使用this关键字。
使用this()语法使用本类中其它构造器;
基本语法结构:
构造器1(参数1,参数2){ 使用参数12赋值的过程...... } 构造器2(参数1,参数2,参数3,参数4){ this(参数1,参数2);//调用构造器1 使用参数34赋值的过程....... }
注意:
-
通过this()的方式,调用别类中其它构造方法,在一个构造器中,只能调用一次;
-
this()必须放在第一行
-
在普通方法中,不允许使用this()的方式调用构造器
方法的重载:
重载方法:方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。
封装
定义:
该隐藏的隐藏,该暴露的暴露(迪米特法则——最少知道原则),有关系的放到一起,没关系的分开放(单一职责原则)
封装性的实现手段
-
访问权限修饰符 public private protected Java项目的构架:项目(Project)->包(Package)->类(Class)
跨包 | 同包跨类 | 本类当中 | |
---|---|---|---|
public | Y | Y | Y |
protected | N | Y | Y |
private | N | N | Y |
-
get/set方法:
仅针对于对象属性使用
类与类之间的关系
-
类与类之间的关系紧密程度的划分标准:内聚性与耦合度
内聚性:用来描述一个功能自己独立完成业务逻辑的能力(不请求别人的能力)
耦合度:用来描述两个结构(方法、类、对象)之间的互相依赖程度高低的标准(需要别人帮忙的程度)
程序开发标准:高内聚低耦合
-
类与类之间有哪些关系:
继承与实现:is-a关系
组合与聚合:has-a关系
关联与依赖:need-a关系
继承(is-a关系)
1.继承关系作用:
作用1:一个类(子孙)继承另一个类(先祖),子孙类型就能获取祖先中的所有成员(属性+方法)
作用2:子孙类在继承先祖类的过程中,还会获得祖先类的身份
2.继承关系名词解释:
关键词1:拓展 extends
关键词2:子类 Sub Class
关键词3:父类 Super Class
关键词4:单继承 子类只能有一个父类,父类可以有多个子类
3.代码实现:
public class 子类 extends 父类{}
4.继承与访问:
-
说明1:子类继承父类,只能通过子类对象访问父类中的使用public、protected权限修饰的成员,在本报当中访问父类使用private的权限修饰的成员,依然不能通过子类进行访问
-
说明2:子类能够继承父类的成员,但不包括父类构造方法。
-
自类虽然不能继承父类的构造方法,但可以通过一些方式调用父类的构造方法:super关键字
4.调用父类构造器
基本语法:
子类名称(){ super(参数1,参数2,......);//调用父类构造器 }
基本案例:
public class Student extends Person { private int math; private int chinese; private int english; public Student(String name, int age, String id, int math, int chinese, int english){ super(name, age, id); //调用父类有参构造器 this.math = math; this.chinese = chinese; this.english = english; } }
注意:通过super()调用父类中声明的构造方法,其写法和通过this()调用本类中的构造器,用法一致。
说明1: this()调用本类构造器和super()调用父类构造器,都是要占据构造方法的逻辑第一行的,所以this()和super()二者不能共存,只能够选其一执行。
说明2:在子类构造器当中,要求必须显式或者隐式的调用父类当中提供的某一个构造器(先有爹再有儿子),但是如果在子类构造器当中,没有显示声明super调用父类的构造器的话,编译器会在这个子类构造器当中添加一个默认的、隐式的父类无参构造器(super())的调用。
所以,如果父类没有提供无参构造器(显示声明的,也可以是默认的)的话,那么子类的构造器在编译过程中,要求必须手动选择并调用一个父类的有参构造器。
父类:
public class Person { private String name; private int age; private String id; /* public Person(){ } */ public Person(String name, int age, String id) { this.name = name; this.age = age; this.id = id; System.out.println("这是父类Person类的有参构造器"); } }
子类:
public class Student extends Person { private int math; private int chinese; private int english; public Student() { //如果父类当中没有提供无参构造器的话,这个子类的构造方法将会报错 //因为没有选择手动调用一个父类的有参构造器 //隐藏:super() } public Student(int math, int chinese, int english) { //如果父类当中没有提供无参构造器的话,这个子类的构造方法将会报错 //因为没有选择手动调用一个父类的有参构造器 //隐藏:super() this.math = math; this.chinese = chinese; this.english = english; } public Student(String name, int age, String id, int math, int chinese, int english){ //这里没有报错,是因为手动调用了父类中提供的有参构造器,替代了默认的super() super(name, age, id); //调用父类有参构造器 // this(math, chinese, english); //这种写法会产生异常 this.math = math; this.chinese = chinese; this.english=english; } }
总结:
情况1:父类当中提供了无参构造器(包括隐式提供的和显示提供的),此时子类构造器可以手写super()表示显式调用父类无参构造器,但是不写也不会报错,因为编译器会自自动为子类构造器添加一个隐藏的super();
情况2:父类当中没有提供无参构造器,只有各种各样的有参构造器:此时子类构造器则不再允许使用super(),哪怕不去手动声明,默认的super()也不允许存在了此时为了保证子类构造器的正确,必须在子类构造器当中手动选择调用一个父类提供的有参构造器:super(参数1, 参数2, ...)
说明3:在调用构造器的过程当中,JVM总是遵从“先父类,再子类”的流程
Person类
public class Person { public Person() { System.out.println("这是Person类无参构造器"); } }
Student类
public class Student extends Person{ public Student(){ System.out.println("这是Student类的无参构造器") } }
LittleStudent类
public class LittleStudent extends Student{ public LittleStudent(){ //隐藏的super() System.out.println("这是LittleStudent类的无参构造器") } }
运行结果
这是Person类无参构造器 这是Student类的无参构造器 这是LittleStudent的无参构造器
5. 继承关系在内存中的结构:
说明:每一层继承之后,子类在内存当中就相当于多了一个父类核心;在创建子类对象的时候,必须先将这个父类核心对象创建出来,否则子类对象无法实例化:因为属性和方法是以对象为存在载体的,所以父类对象核心不存在,则子类复发得到(继承到)父类中的属性和方法。这也就解释了在实例化子类对象的时候,为什么会先运行父类构造器,再运行子类构造器。
6.最高父类:Object类(祖宗类):
说明:如果在Java中,某一个类型没有手动声明继承自某一个父类(使用extends关键字),那么这个类会被编译器认为是自动(默认、隐式)继承自Object类;
同时Object类也是Java中所有类型(不包含基本数据类型)的最高父类。
7.继承关系的优点与缺点:
优点:
-
优点1:子类继承父类,能够继承父类当中所有的属性和方法(子类对象能不能访问,还得看父类属性和方法的访问权限修饰符),最大程度上的做到了代码重用;
-
优点2:子类继承父类,并没有被父类中的成员所限制,子类依然可以扩展自己的成员,同时子类还能够重写(覆盖)从父类中继承的成员。
缺点:
-
缺点1:在继承关系当中,父类和子类的耦合度,相较于其他5种关系是最高的,一旦父类发生改变,子类将在不会得到任何通知的前提下被动改变——开闭原则;
-
缺点2:随着继承层数的增加,子类对象在内存当中的大小是越来越大的,因为每一个子类对象都依赖层层的父类对象核心,作为继承得到的成员的载体;
-
缺点3: Java中的继承是单继承,则表示无法从不同的父类当中获取更为丰富的属性和方法(Python是多继承);
-
缺点4:继承关系当中,为了保证子类一定能够访问父类当中提供的成员,那么久必须保证这个成员在父类当中的访问权限不是private,会破坏父类的封装性——protected关键字。