day07
一、构造方法
作用:用来创建一个类的对象;用来初始化类中的成员
1.1 格式
1. 修饰符一般为public (在特殊的时候会用private修饰)
2. 构造方法没有返回值类型,连void都没有
3. 构造方法名必须和类名保持一致
4. 构造方法可以有参也可以无参
5. 构造方法没有return(如果非要加return的话,那么就写成return;)
public 类名(参数列表) {
}
1.2 注意事项
1. 构造方法不能手动调用,它会在我们创建对象的时候默认被jvm虚拟机调用
2. 构造方法可以有参也可以无参
无参的时候:通过无参构造方法创建对象,然后通过setXxx方法赋值
有参的时候:通过带参构造方法创建对象的同时就给成员变量赋值
3. 构造方法可以重载(一般我们都是无参和带参都写)
4. 一个类中默认带有一个无参的构造方法
5. 一旦我们声明了一个无参构造方法或者带参构造方法,那么会将原来默认带有的无参构造方法给覆盖掉
package com.ujiuye.constructordemo2;
public class Person {
String name;
int age;
public Person(){
System.out.println("无参构造方法");
}
public Person(String name, int age){
this.name = name;
this.age = age;
System.out.println("带参构造方法");
}
}
public class Demo {
public static void main(String[] args) {
//1. 创建对象
//无参只是创建了一个对象
Person p2 = new Person();
//带参创建对象并给成员变量赋值
Person p = new Person("张三", 33);
//2. 输出
System.out.println(p.name + "---" + p.age);
System.out.println(p2.name + "---" + p2.age);
}
}
1.3 this和构造方法之间的关系 【了解】
this(); 访问本类的无参构造方法
this(参数); 访问本类的带参构造方法
注意:this调用构造方法的时候不能放在和this参数一致的构造方法中
1.4 类中成员的初始化顺序
默认初始化--->显示初始化--->构造初始化
二、类中的成员方法
-
有参或者无参
-
有参
public void setName(String name){ this.name = name; }
-
无参
public String getName(){ return name; }
-
-
有返回值或者无返回值
-
有返回值
public String getName(){ return name; }
-
无返回值
public void setName(String name){ this.name = name; }
-
总结:类中可以放任何方法
三、一个类的标准写法
成员变量
一般都用private进行修饰
构造方法
一般无参和有参都写
成员方法
setXxx和getXxx方法
练习:
1. 用标准的写法完成人类,并在测试类中测试
2. 用标准的写法改进昨天的手机案例,并在测试类中测试
package com.ujiuye.basicdemo;
public class Phone {
//成员变量
private String brand;
private String color;
private int price;
//构造方法
//无参
public Phone() {
}
//带参
public Phone(String brand, String color){
this.brand = brand;
this.color = color;
}
public Phone(String brand, String color, int price){
this.brand = brand;
this.color = color;
this.price = price;
}
//成员方法 getXxx和setXxx方法
public void setBrand(String brand){
this.brand = brand;
}
public String getBrand(){
return brand;
}
public void setColor(String color){
this.color = color;
}
public String getColor(){
return color;
}
public void setPrice(int price){
this.price = price;
}
public int getPrice(){
return price;
}
//定义一个show方法,用来统一打印所有的成员变量
public void show(){
System.out.println(brand + "---" + color + "---" + price);
}
}
public class Demo2 {
public static void main(String[] args) {
//第一种方式:
Phone p = new Phone();
p.setBrand("华为");
p.setColor("黑色");
p.setPrice(19999);
System.out.println(p.getBrand() + "---" + p.getPrice() + "---" + p.getColor());
//第二种方式:
Phone p2 = new Phone("一加", "黑色", 4999);
// System.out.println(p2.getBrand() + "---" + p2.getPrice() + "---" + p2.getColor());
p2.show();
}
}
四、静态static
先建立一个Person类,类中有成员变量(姓名、年龄、国家),有构造方法(无参和带参),写一个测试类进行测试。
package com.ujiuye.staticdemo;
/*
人类
*/
public class Person {
String name;
int age;
//国家
static String country;
//构造方法
public Person(){
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
public Person(String name, int age, String country){
this.name = name;
this.age = age;
this.country = country;
}
//定义一个show方法,用来展示所有的成员变量
public void show(){
System.out.println(name + "---" + age + "---" + country);
}
}
/*
分析如下代码,我们发现了一个问题:
创建的多个对象的姓名和年龄是不同的,但是国家是相同的
不同的对象的姓名和年龄不同,所以每个对象都给姓名和年龄开辟一个空间没有问题,
但是不同对象的国家是相同的,每个对象再给国家都开辟一个空间就不合理了。
(因为不仅造成了一定的空间浪费,管理着也十分不方便)
如何解决?
我们可以将这个国家单独定义在一个地方,而不是每个对象都进行定义。这样我们节省空间了管理也方便了。
如何将国家单独定义在一个地方?
Java中提供了一个关键字static,被static修饰的变量,就变成了一个静态的变量。
静态的变量能被所有的对象所共享(但并不独属于某一个对象)
静态的变量不是存放在堆上的,而是存放在方法区的静态区中的。
*/
public class Demo {
public static void main(String[] args) {
Person p3 = new Person("哆啦A梦", 5, "中国");
p3.show();
Person p = new Person();
p.name = "新垣结衣";
p.age = 27;
// p.country = "日本";
p.show();
Person p2 = new Person("大雄", 7);
// p2.country = "日本";
p2.show();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OK4Gvj6L-1620291038037)(img/image-20210414143206350.png)]
4.1 特点
1. 随着类的加载而加载
2. 优先于所有对象而存在
3. 被类所有对象所共享
4. 静态变量一般是通过静态的方式来访问的: 类名.静态变量名;
4.2 注意事项
静态方法格式:
权限修饰符 static 返回值类型 方法名(参数列表) {
}
1. 静态方法中可以访问非静态的变量吗?
不可以。 因为被static修饰的内容(变量、方法)随着类的加载而加载,并且优先于对象而存在的,而非静态的变量是跟着对象的存在而存在的。如果静态方法可以访问非静态变量的话,那么就是已经存在的地方访问不存在的内容,逻辑上出现错误。
2. 静态方法中可以访问非静态的方法吗?
不可以。 因为被static修饰的内容(变量、方法)随着类的加载而加载,并且优先于对象而存在的。如果静态方法可以访问非静态方法的话(非静态方法是可以访问非静态变量的),就相当于静态方法间接的访问了非静态变量,逻辑上出现错误。
注意:静态只能访问静态
3. 非静态可以访问静态吗?
可以。 因为非静态是后出来的,所以肯定可以访问先出来的静态方法或者静态变量
学生类、老师类、医生类、护士类、军人类…
五、继承
之前定义的很多类,它们都有共同的内容,比如姓名、年龄、吃饭、睡觉等。我们可以将这些共同的内容给抽取出来,放到一个公共的类中,以上的类就不再需要定义这些重复的内容,而只需要通过某种特定的格式和公共的类产生关联性,就可以使用这个公共类中的内容了,这种行为就叫做继承。
5.1 格式
关键字: extends
class 父类 {
}
class 子类 extends 父类 {
}
注意:
1. 公共的类被称为父类、或者基类
2. 继承的类被称为子类、或者派生类
5.2 注意事项
1. 父类的私有成员不能子类被继承(有的教程说父类的私有成员可以被继承,只不过不能访问。实际意思是一样的)
2. 父类的构造方法可以被继承吗? 不可以
原因1:父类的构造方法名必须和父类类名一直,子类的构造方法名必须和子类一致。所以不能继承
原因2:因为构造方法就是用来对类进行初始化的,但是子类的成员肯定不会比父类的成员少,所以子类不会继承父类的构造方法。
5.3 特点
1. 可以单继承
class Father {}
class Son extends Father {} //正确
2. 不可以多继承
class Father {}
class Mother {}
class Son extends Father, Mother {} //错误
class Son extends Father extends Mother {} //错误
3. 可以多层继承(继承体系)
class GrandFather {}
class Father exntends GrandFather {}
class Son extends Father {} //正确
5.4 继承中构造方法之间的关系
子类用构造方法(无论是有参或者带参)创建对象的时候,都会默认的访问父类的无参构造方法。
为什么?
因为子类可以使用父类的成员,要想使用这父类的成员,那么父类的成员肯定要先进行初始化。所以子类无论是用带参或者是无参构造方法创建对象的时候,都会先访问父类的无参构造方法(先让父类完成初始化。)
5.5 super关键字 【了解】
可以类比this关键字来理解
this:哪个对象调用方法,方法中的this就代表哪个对象(this就是一个对象)
super:可以认为是指向父类的对象(suepr实际上是指向父类的地址)
this和super访问成员时候的区别:
访问成员变量的时候:
this: 即可以访问本类的变量,也可以访问父类的变量
super: 只能访问父类的变量
格式:
this.变量名;
super.变量名;
访问成员方法的时候:
this: 既可以访问本类的方法,也可以访问父类的方法
super: 只能访问父类的方法
格式:
this.方法名();
super.方法名();
访问构造方法的时候:
this:
this(): 访问子类的无参构造方法
this(...):访问子类的带参构造方法
super:
super(): 访问父类的无参构造方法
super(...):访问父类的带参构造方法
注意事项:
1. 子类在创建对象之前会默认访问父类的无参构造方法(实际上就是在子类构造方法的第一行有一个super())
2. 一旦在子类构造方法的第一行写上一个super()或者super(参数);那么就会将默认的super();给替换掉
3. super()和this()必须要放在构造方法的第一行
4. this()和super()访问构造方法的时候不能共存
访问本类的方法,也可以访问父类的方法
super: 只能访问父类的方法
格式:
this.方法名();
super.方法名();
访问构造方法的时候:
this:
this(): 访问子类的无参构造方法
this(…):访问子类的带参构造方法
super:
super(): 访问父类的无参构造方法
super(…):访问父类的带参构造方法
注意事项:
1. 子类在创建对象之前会默认访问父类的无参构造方法(实际上就是在子类构造方法的第一行有一个super())
2. 一旦在子类构造方法的第一行写上一个super()或者super(参数);那么就会将默认的super();给替换掉
3. super()和this()必须要放在构造方法的第一行
4. this()和super()访问构造方法的时候不能共存