- 类 的 升级
- 构造方法
- 构造方法的定义:
- 自行创建一个构造方法
- 有参数的构造方法:
- 构造方法的重载:
- this 关键字
- this 修饰属性
- this 修饰方法
- this 修饰构造方法
- 代码块
- 本地代码块
- 构造代码块:
- 静态代码块
- 构造方法,实例化代码块,静态代码块 的在程序中的执行顺序
- 匿名对象
- 总结:
- 最后:
记得那些真心珍惜身边的家人和朋友,丢掉那些虚伪和曾经的伤口心路不在何乎晚,留情若不争,何必将就有些事走着走着就懂了,有些人走着走着就散了
人生如逆旅。
你我都是路上的行人,谁也不能保证接下来的路能永远相伴。
有些人注定在下一个路口,离开,该记得记,大家,丢的丢,该放手时就放手。
人生该记得记,该丢的丢,人生苦短,不要为了不值得的人浪费宝贵的时间,生活很累,别让自己再多承受负担。
————————— 一禅心灵庙语
构造方法
- 构造方法 在一些书籍中又叫 构造器 ,构造函数 这里我是叫 构造方法 ,因为它和方法类似。不过名字什么的不重要,因为都是翻译过来的,不同的人,不同的翻译罢了,但是意思是一样的
- 构造方法是一种比较特殊的方法,它在new实例化对象的时候,会被自动调用它的,从而可以实现对象的属性进行初始化 —— 初值
- 我们在 new 一个对象(创建对象的时候)的执行过程:
- 为我们的对象的存储开辟空间
- 调用合适的构造方法
- 这两个条件必须都满足才能创建出对象出来,少一个都不可以的
构造方法的定义:
- 构造方法的语法规则:
- **构造方法名:**必须要和类名完全一致
- 不可以 有返回值,可以有修饰符
- 同方法一样可以重载
- 并且一个类中至少含有一个构造方法 ,( 当没有自行明确定义构造方法的时候,编译器会自动构造一个无参数的构造方法,供其在实例化对象的时候调用 )
修饰符 构造方法名[和类名保持一致] (形参) {
// 构造方法的方法体
}
class Person {
private String name;
private int age;
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person(); // Person() 调用一个无参构造方法
}
}
- 调用构造方法:
-
上述代码结果
-
观察上述代码,我们是不是发现,我们并没有,定义构造方法 对吧!
-
好的疑问来了?不是说,在实例化一个对象的时候,一定要满足两个条件吗?其中一个便是必须要调用啊构造方法吗?可我们这里,并没有定义构造方法,它又怎么调用呢,为什么,没有报错呢!
-
原因很简单:
- 当我们没有自行明确定义构造方法的时候,我们的好伙伴——编译器 会为我们自动创建一个无参数类型的构造方法 ,虽然你看不到它,所创建的构造方法,但它确确实实是存在的,不然会报错的,
- 为我们的编译器小伙伴点赞
自行创建一个构造方法
- 注意:创建构造方法的语法规则:
class Person {
private String name;
private int age;
public Person() { // 定义一个无参数的构造方法
System.out.println("这是一个无参构造方法");
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
}
}
- 结果:
- 我们可以看到,当我们实例化 一个对象的时候,调用了 我们自行定义的构造方法
- 可见这是否是创建对象必要条件了吧!
有参数的构造方法:
- 当类中我们没有定义任何的构造方法的时候,我们的编译器伙伴会,自动为我们生成一个无参数的构造方法的
- 但是:注意了! 当我们自己定义了一个构造方法的时候,我们的编译器伙伴,就不会为我们创建一个无参数的构造方法了,所以,当你要调用一个,无参数的构造方法的时候,你就必须自行定义一个无参数的构造方法了。 不然的话,就会报错的。如下:
class Person {
private String name = "你好世界";
private int age;
public Person(String name) { // 创建一个有参数的构造方法
System.out.println(this.name);
System.out.println("这是一个有参数的构造方法");
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
}
}
结果:
- 但是,因为我们定义了一个有参数的构造方法,我们就仅仅调用这个有参数的构造方法 就没有问题了,其实这本质上就是构造方法的重载
- 如下:
class Person {
private String name = "你好世界";
private int age;
public Person(String name) { // 创建一个有参数的构造方法
this.name = name;
System.out.println(this.name);
System.out.println("这是一个有参数的构造方法");
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person("Hello World");
// 调用一个有参数的构造方法,传值为”Hello World“
}
}
- 结果:
构造方法的重载:
- 我在前面中的构造方法的规则中 提到了一茬 调用合适的构造方法 其中的合适 的意思就是:寻找合适的构造方法,并调用它 ,就是重载
- **重载:**
- 前提 是要在同一个类当中
- 构造方法同样是方法,所以重载的构造方法,也是需要相同的,不过我们的构造方法名都是类名,所以在这一点上,我们可以,忽视
- 可以是参数列表中的 参数类型不同
- 可以是参数列表中的 参数个数不同
**如下:**
class Person {
private String name;
private int age;
public Person() {
System.out.println("无参数的构造方法");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println(this.name);
System.out.println(this.age);
System.out.println("有两个参数 的构造方法 ");
}
public Person(String name) {
this.name = name;
System.out.println(this.name);
System.out.println("有一个参数 的构造方法");
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person(); // 调用一个无参数的构造方法
Person person1 = new Person("小华",18); // 调用一个有两个参数的构造方法
Person person2 = new Person("你好世界");
}
}
- 结果:
this 关键字
- this 关键字指代的是对象自身,通过 this 关键字可以指向自身地址空间,简要内存分析以我们的 Person 对象为例
- this 关键字的作用:
- this 修饰属性( 成员变量) ,可以在本类中访问自身属性。格式:
this.属性名 ;
- this 修饰方法,可以在本类中访问自身方法,提高代码的复用性 格式:
this.方法(参数);
- this 修饰构造方法,使本类构造方法之间可以相互调用,提高代码的复用性 ,格式:
this(构造方法中有参数就写,没有就不用了)
this 修饰属性
- 这里主要是用在,我们的参数类中的属性,名称相同的时候,发生:局部变量化,的冲突,导致赋值失败:
- 如下:不用 this 修饰属性,参数名 和类中的属性相同的冲突:
class Person {
private String name;
private int age;
public void test(String name, int age) {
name = name; // 局部变量优先,局部变量自己赋值给自己,
age = age; // 属性并没有被赋值到
}
public void print() {
System.out.println("name:"+name); // null
System.out.println("age:"+age); // 0
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
person.test("Hello World",18);
person.print();
}
}
- 结果:
- 如下:被this 修饰的属性
class Person {
private String name;
private int age;
public void test(String name, int age) {
this.name = name;
this.age = age;
}
public void print() {
System.out.println("name:"+name); // null
System.out.println("age:"+age); // 0
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
person.test("Hello World",18);
person.print();
}
}
- 结果:
- 我们可以看到我们赋值成功了,这就是this.修饰属性 的效果
this 修饰方法
- 这个和修饰属性是一样的
class Person {
private String name;
private int age;
public void print() {
this.test(); // 使用 this 修饰方法的调用
}
private void test() {
System.out.println("这是一次,this.修饰方法的测试");
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
person.print();
}
}
- 结果:
this 修饰构造方法
-
当使用:this修饰构造方法的注意事项:
-
this( ) 调用自己的构造方法,只能在构造方法中使用,不然是会报错的
-
只能写在第一行当中,一定要为第一条语句才行,不然会报错
class Person {
private String name;
private int age;
public Person() {
this("你好世界",18);
}
public Person(String name, int age) {
System.out.println(name);
System.out.println(age);
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
}
}
- 结果:
- 不在构造方法中使用 this调用构造方法 报错,如下:
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this("你好世界",18);
System.out.println(name);
System.out.println(age);
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
}
}
- **报错结果:**
- 当 this 调用构造方法 不是作为第一行第一条语句的情况的报错:
class Person {
private String name;
private int age;
public Person() {
this("你好世界",18);
this("你好世界"); // this 调用构造方法必须为第一条语句才行
}
public Person(String name) {
System.out.println(name);
}
public Person(String name, int age) {
System.out.println(name);
System.out.println(age);
}
}
public class Blog02 {
public static void main(String[] args) {
Person person = new Person();
}
}
- **报错结果:**
面试问题:this 关键字代表的是对象,这句话是不是对的?为什么? 答:是不对的,this 关键字代表的是引用当前对象,因为: 我们在构造方法中使用 this关键字的时候,并没有出现报错的情况 而我们在实例化对象的时候,必须满足两个必要条件: 1,为对象开辟空间, 2.调用完合适的构造方法,当满足了这两个条件对象才会被创建出来, 而我们在 构造方法中使用 this 关键字,如果它代表的是:当前对象的话, 而我们的构造方法又没有调用完, 所以我们还并没有创建出对象出来, 我们的 JVM 虚拟机会暴力强制报错的,而事实上,并没有报错, 综上所述:this 代表的不是对象。而是当前对象的引用
代码块
- 用的花括号=={ }== 包围的一段代码称之为 代码块。按照代码块的声明位置的不同,可以将代码块分为:4 种类型:本地代码块(又称为 普通代码块),构造代码块,静态代码块,同步代码块, 这里同步代码块我们不介绍了
- 注意: 构造代码块,和静态代码块 在类中一般是一定会执行的
{
}
本地代码块
- 本地代码块一般用于约束变量的作用域的,如:**方法名后的{ }, 分支结构中的{ },循环结构中的 { },方法体中的 { } ** 这些都是 本地代码块
public class Blog02 {
public static void main(String[] args) {
int i = 1;
{
System.out.println("我是方法体中的本地代码块");
}
if(1 == i) {
System.out.println("我是分支结构 if中的本地代码块");
}
while(1 == i) {
System.out.println("我是循环语句 while中的本地代码块");
i++;
}
}
}
- **结果:**
构造代码块:
- 这个名字也许我们有点陌生,但是它还有另外一个名字:实例化代码块 (不加修饰符static )
- 是定义在类当中使用的 ,构造代码块一般用于初始化实例成员变量的。
- 如下:
class Person {
private String name;
private int age;
{
System.out.println("我是构造代码块又叫 实例化代码块");
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
}
}
- 结果:
静态代码块
- 与实例化代码块相反
- 静态代码块 被static 关键修饰,一般用于初始化静态成员属性
- 同理静态的是无法直接访问非静态的,想了解更多的话,请移步到这 Java中为什么静态的不能访问非静态
- 如下:
class Person {
private String name;
private int age;
static {
System.out.println("我是静态代码块");
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
}
}
- 结果:
构造方法,实例化代码块,静态代码块 的在程序中的执行顺序
- 先是执行静态代码块 因为静态的是和类一起加载到内存==(方法区)== 当中的
- 其次是实例化代码块
- 最后是构造方法
- 看如下结果:
class Person {
private String name;
private int age;
public Person() {
System.out.println("我是构造方法");
}
{
System.out.println("我是构造代码块又叫 实例化代码块");
}
static {
System.out.println("我是静态代码块");
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
}
}
- 结果:
- 静态代码块只会执行一次,只会生成一份,所有对象共用这一份的
- 如下:我是实例化俩个对象看看结果
class Person {
private String name;
private int age;
public Person() {
System.out.println("我是构造方法");
}
{
System.out.println("我是构造代码块又叫 实例化代码块");
}
static {
System.out.println("我是静态代码块");
}
}
public class Blog03 {
public static void main(String[] args) {
Person person =new Person();
System.out.println("*********************");
Person person2 = new Person();
}
}
- 结果:
- 如果定义的都为静态的,那么执行的顺序就和 定义静态的前后顺序有关了,以最后一次为准
- 如下:
class Person {
private static int count = 0; // 注意这里:
static { // 注意这里:
count = 99;
System.out.println("静态代码——————");
}
public void func() {
System.out.println("count:"+count);
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
person.func();
}
}
- 我们记住下面这个结果:
- 我们再把静态代码,和静态成员变量 交换一下位置,再看看结果
class Person {
static { // 注意这里:
count = 99;
System.out.println("静态代码——————");
}
private static int count = 0; // 注意这里:
public void func() {
System.out.println("count:"+count);
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
person.func();
}
}
- 结果:
匿名对象
- 匿名只是表示没有名字的对象
- 没有引用对象的称为**“匿名对象”**
- 匿名对象只能在创建对像时使用==(new)== 就是实例化(new)的同时并引用使用
- 如果一个对象只是使用一次的话,后面不需要用了,可以考虑使用匿名对象,访问,一般情况下是不建议的
- 因为只能用一次吗?
- 使用格式如下:
new 类名( ).方法或者是属性;
- 如下:
class Person {
private String name;
private int age;
public void eat() {
System.out.println("吃饭了吗");
}
public void test() {
System.out.println("这是一次测试");
}
}
public class Blog03 {
public static void main(String[] args) {
Person person = new Person();
person.eat();
person.test();
System.out.println("下面的是使用匿名对象调用:");
System.out.println("***********************");
new Person().eat();
new Person().test();
}
}
- 结果:
总结:
- 一个类可以产生无数的对象,类就是模板,类似于C语言中的结构体 ,对象就是具体的实例化
- 类中定义的属性,大概分为几类: 类属性,对象属性。其中被 static 所修饰的数据属性称为类属性,static 修饰的方法称为类方法 ,特点就是不依赖于对象,我们只需要通过类名 就可以调用其属性或者方法
- 静态代码块优先执行 ,其次是实例代码块,最后是 构造方法
- this 关键字代表的是当前对象的引用,并不是代表当前对象
最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多指教,谢谢大家!后会有期,江湖再见!



