this关键字
出现的场景
当类的成员变量和方法的参数列表中变量的名字出现重复的时候,为了让计算机能够对相同的变量名进行区分,就引入 this 关键来表示当前类的一个对象,或者谁来调用该方法,那么this就代表谁this 关键字的作用就是为了区分谁是成员变量,谁是局部变量
变量访问原则 -- 就近原则
当出现重复变量名时,在进行访问的时候,看谁离的近,谁近当作谁
当访问变量时,如果变量名前面加了 this 关键字,让变量表示类的属性,不在使用就近原则去访问
构造方法的定义
访问修饰词 类名 (参数列表) {
}
格式说明
① 构造方法没有返回值类型
② 构造方法的方法名必须跟类名保持一致
③ 构造方法中可以存在 return 语句,但是一般情况不写
构造方法的分类(根据有无参数列表)
① 有参数列表的构造方法:有参构造
② 没有参数列表的构造方法:无参构造
当没有手动的构造方法时,系统会默认提供无参构造供编程人员使用;
一旦编程人员在类中定义了构造方法,系统将不会再提供默认的无参构造,如果这个时候还想使用无参构造就要手动将无参构造定义出来。
构造方法的作用
① 创建对象的时候被调用
② 初始化属性(有参构造是将创建对象时传入的实参赋值给类的属性,无参构造让属性保持默认值)
属性初始化的过程
默认初始化(第一步)
在内存分配的时候进行
(显示)手动初始化(第二步)
定义属性的时候进行手动赋值
构造方法初始化(第三步)
创建对象,调用构造方法的时候初始化
三种初始化方式的内存理解
public class Car {
String name = "BYD";
double price = 50000;
public Car(String name, double price) {
this.name = name;
this.price = price;
}
public Car() {
}
}
public class Test_Car {
public static void main(String[] args) {
Car car = new Car("bmw",2000000);
}
}
static 静态
使用 static 修饰属性
例如:当我们在创建多个对象时发现这几个对象都具有相同的属性值,那么久可以将该属性定义为静态的属性,这样做后每次创建对象的时候该对象就会拥有个静态的属性值,不需要手动的再去赋值
public class Person_Man {
static String sex = "男";
String name = "小红";
public Person_Man(String sex) {
this.sex = sex;
}
public Person_Man() {
}
}
public class Test_Man {
public static void main(String[] args) {
Person_Man p1 = new Person_Man("小明");
Person_Man p2 = new Person_Man("小黑")
Person_Man p3 = new Person_Man("小黄");
System.out.println(p1.sex);
System.out.println(p2.sex);
System.out.println(p3.sex);
Person_Man.sex = "女";
System.out.println(p1.sex);
System.out.println(p2.sex);
System.out.println(p3.sex);
}
}
静态修饰成员方法或者成员变量时
① 被 static 修饰的方法称为静态方法,被 static修饰变量叫做静态变量;static 写在访问修饰词的后面
② 静态方法只能访问静态属性或者静态方法,不能访问非静态的内容
原因:static 修饰的内容会在字节码文件被加载时就加载到方法区中的静态区;非静态的内容需要在创建对象后才表示加载完成,所在静态不能访问非静态
③ 静态方法中不能有 this 关键字
原因:因为 static 随着类的加载而存在,this关键字表示的当类的对象;如果在静态方法中允许出现 this,就表示还在加载字节码文件时,对象就已经存在,这样显然是不合理的;
④ 总之,静态不能访问非静态,但是非静态可以访问静态
静态变量和非静态变量的区别
① 从内存上区分静态变量:
方法区的静态区非静态变量:
堆内存的对象中
② 生命周期:一个事物从产生到消亡的过程
静态变量:随着类的加载而存在,随着类的消亡而消亡
非静态变量:随着对象的创建而存在,对象的消亡而消亡
③ 定义方式:
静态变量:访问修饰词 static 数据类型 变量名 = 值;
非静态变量:访问修饰词 数据类型 变量名 = 值;
④ 访问方式:
静态变量:类名.静态变量 或者 对象.静态变量
非静态变量:只能使用 对象.变量
static 的应用
① 制作工具类:将工具类中所有的方法和属性都用 static 进行修饰
例如:Math、Arrays、·······
② 静态代码块(优先进行资源的加载)
static{
需要优先执行的程序写在这里
}
继承的概念
先抽取同一类事物的共性(属性、行为)来定义成一个超类,后续如果在需要这些共性的时候就使用 extends 关键字来继承获取这些定义在超类中非私有的共性;
一个类如果没有明确的指定其父类是谁,那么 Object 就是它的父类,这个类就可以使用 Object 中定义好的一些方法
继承的格式
public 自定义类 extends 超类{
可以会用在超类中定义好的非私有化的属性和行为
}
自定义类就称为子类,超类就称为父类
使用继承实现如下的程序设计
程序员:属性 -- 姓名、工号、部门、年龄、工龄、工资、项目提成;行为 -- 工作
项目经理:属性 -- 姓名、工号、部门、年龄、工龄、工资、管理津贴;行为 -- 工作
前台小姐姐:属性 -- 姓名、工号、部门、年龄、工资、工龄;行为 -- 工作
程序设计的步骤:
① 先抽取出所有员工的共性,定义成一个超类 -- 员工类(以较少的为准)
② 分别定义程序猿类,项目经理类、小姐姐类来继承员工类
③ 当自定义中有除了超类中定义以外的属性或者行为时,需要在子类中重新定义
注意:不要为了钱,到处乱认爹;继承的设计一定要存在属于的关系,子类一定要是父类的一种
代码实现
public class Employee{
String name;
String id;
String department;
int age; double work_age;
double salary;
public void work(){
}
}
public class Programmer extends Employee{
double salary_other;
}
public class Manager extends Employee{
double salary_other;
}
public class YoungSister extends Employee{
}
继承中的注意事项
① 私有的成员(属性、行为)不能被继承
② 父类的构造方法不能被继承
java 要求构造方法的方法名必须跟类名一致,如果构造方法能继承,就以为在子类中拥有父类的构造方法,但是在子类的构造方法名字必须跟子类的类名一致;所有说在继承中构造方法不能被继承
③ 构造方法虽然不能被继承,但是在子类中可以调用父类的构造方法(必须调用)
a. 如果父类中没有定义构造方法,那么在子类中系统会默认调用父类的无参构造;在子类的构造方法的第一行默认加上代码 super();
b. 如果父类中定义了有参构造并且没有无参构造,在子类的构造方法的第一行必须手动的调用父类的构造方法
c. 父类中既有有参构造又有无参构造,在子类中可以手动调用父类的构造方法,也可以让系统默认调用
练习:有正方形(边长 = 6)、长方形(长 = 5、宽 = 7)、圆形(半径= 2、π),他们都有共同的行为求周长和面积并且通过使用测试类分别打印三个图形的周长和面积;
public class Graghisc {
double x;
public void getPerimeter(){
}
public void getArea(){
}
}
public class Square extends Graghisc{
}
public class Rectangle extends Graghisc{
double width;
}
public class Circular extends Graghisc{
Double PI = Math.PI;
}
继承中方法的重写
① 子类重写父类的非私有、非终态的方法;
② 重写的前提:必须存在继承或者实现关系
③ 重写的要素:
a. 子类中方法名需要个父类中定义的方法名一致
b. 子类中方法的返回值类型必须跟父类一致
c. 子类中方法的参数列表跟父类中方法必须一致(个数、类型、顺序,三个都要一致)
d. 子类中方法的访问权限修饰词类型不能小于父类方法的访问权限
e. 子类中方法抛出的异常,不能比父类方法抛出的异常多。范围不能比父类方法的范围大
方法重写的应用
因为在父类中我们只是抽取了行为,没有办法抽取子类中具体的实现过程,于是就需要在子类中对父类的方法进行重写来指定子类自己行为的实现过程
方法重写检验 -- @Override注解
如果是在进行父类方法的重写,那在子类方法的上面加上注解后程序不会报错,一旦在某个方法上面加上注解后程序出现报错,那就证明注解下方的方法不是在进行父类方法的重写
继承中成员变量的访问
① 当子类和父类中定义有相同的变量时,子类既可以访问父类中定义的变量,也可以访问子类中定义的变量,父类只能访问父类中定义的变量,不能访问子类中定义的变量
② 当子类和父类中拥有相同的变量时,并且在子类方法中还有相同的局部变量,优先考率就近原则;如果想要区分父类子类和局部变量,需要变量的前面加上 this /super;this表示本类中定义的属性,super表示父类中定义属性
③ 如果在子类中没有定义变量,在访问的时候会自动往上去查找,一直找到 Object 类,如果都没有就出现成编译报错,否则使用就近原则