Java筑基-面向对象


Java-面向对象

一、类和对象

1、类和对象的关系

万事万物皆对象

对象就是具体的事物,具体的实体,具体的实例,模板下具体的产品。

类:类是抽象的,是一个模板。

2、创建类

java 复制代码
package com.company.TestOOP;

public class Person {
    //名词------》属性------》成员变量------》放在类中,方法外
    String name;
    int age;
    double weight;
    double height = 175;

    //动词------》方法
    //吃饭
    public void eat() {
        int num = 20; //局部变量,放在方法中,必须进行初始化
        System.out.println("吃饭");
    }

    public void sleep(String address) {
        System.out.println("我在睡觉地点在:" + address);
    }

    //自我介绍
    public String interduce() {
        return "我的名字是:" + name + ",我的年龄" + age + ",我的身高是:" + height + ",我的体重是:" + weight;
    }

}

3、创建对象

第一次加载类的时候,会进行类的加载,初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值。
再次创建对象时,就不会进行类的加载了,类的加载只在第一次需要的时候加载一次。
不同的对象,属性有特有的值,但是方法都是调用类中通用的方法。
对象的属性是独立的方法;
各个对象的方法是共享的。

java 复制代码
package com.company.TestOOP;

public class Test {
    public static void main(String[] args) {
        //创建一个人类的具体的对象/实例:
        //Person属于引用数据类型
        //创建一个对象,对象的名字叫zs
        //第一次加载类的时候,会进行类的加载,初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值
        Person zs = new Person();
        zs.name="kobe";
        zs.age=19;
        zs.height=180;
        zs.weight=170;


        //再次创建对象时,就不会进行类的加载了,类的加载只在第一次需要的时候加载一次。
        Person ls = new Person();
        ls.name="james";
        ls.age=19;
        ls.height=180;
        ls.weight=170;

        System.out.println(ls.name);
        System.out.println(zs.name);

        //不同的对象,属性有特有的值,但是方法都是调用类中通用的方法。
        //属性,各个对象的属性是独立的
        //方法:各个对象的方法是共享的
        ls.eat();
        zs.eat();
        zs.sleep("酒店");
        String s = ls.interduce();
        System.out.println(s);
    }
}
java 复制代码
james
kobe
吃饭
吃饭
我在睡觉地点在:酒店
我的名字是:james,我的年龄19,我的身高是:180.0,我的体重是:170.0

4、成员变量与局部变量

区别:

1、代码中位置不同:

成员变量:在类中,方法外。

局部变量:方法中定义的变量,代码块中定义的变量

2、代码的作用范围

成员变量:当前类的很多方法

局部变量:当前一个方法(当前代码块)

3、是否有默认值

成员变量:有

局部变量:无

4、是否要初始化
成员变量:不需要,不建议初始化,后续使用的时候再赋值即可。

局部变量:一定需要,不然使用的时候直接报错。

5、内存中位置不同

成员变量:堆内存

局部变量:栈内存

6、作用时间不同

成员变量:当前对象从创建到销毁

局部变量:当前方法从开始执行到执行完毕

5、构造器

5.1、创建对象的过程

1、第一次遇到Person的时候,进行类的加载(并且只加载1次)
2、创建对象,为这个对象在堆中开辟空间
3、为对象进行属性的初始化动作

new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)。

调用构造方法的时候,如果你的类中没有写构造器,那么系统会默认分配一个构造器,只是我们看不到罢了。

可以自己显示的将构造器编写出来。

5.2、构造器的格式

java 复制代码
 [修饰符] 构造器名字(){

 }

5.3、构造器和方法的区别

1、没有方法的返回值类型
2、方法体内部不能有return
3、构造器的名字很特殊,必须和类名一模一样

5.4、构造器的作用

不是为了创建对象,因为在调用构造器之前,这个对象已经创建好了,并且属性有默认的初始化的值。
调用构造器的目的:是给属性进行赋值操作

注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
实际上:我们只要保证空构造器的存在就可以了,里面的东西不用写。

java 复制代码
package com.msb;

public class Person {
    //属性
    String name;
    int age;
    double height;

    //构造器:没有任何参数的构造器;空参构造器
    public Person(){
        //注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
//        age = 19;
//        name = "kobe";
//        height = 180;
    }

    //方法
    public void eat(){
        System.out.println("吃饭");
    }
}
java 复制代码
package com.msb;

public class Test {
    public static void main(String[] args) {
        //创建一个Person类的具体的对象/实例/实体
        /*
        创建对象的过程:
        1、第一次遇到Person的时候,进行类的加载(并且只加载1次)
        2、创建对象,为这个对象在堆中开辟空间
        3、为对象进行属性的初始化动作

        new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)
        调用构造方法的时候,如果你的类中没有 写构造器,那么系统会默认分配一个构造器,只是我们看不到罢了
        可以自己显示的将构造器编写出来。
        构造器的格式:
        [修饰符] 构造器名字(){

        }
        构造器和方法的区别:
        1、没有方法的返回值类型
        2、方法体内部不能有return
        3、构造器的名字很特殊,必须和类名一模一样

        构造器的作用:不是为了创建对象,因为在调用构造器之前,这个对象已经创建好了,并且属性有默认的初始化的值。
        调用构造器的目的:是给属性进行赋值操作

        注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
        实际上:我们只要保证空构造器的存在就可以了,里面的东西不用写。
        */

        Person zs = new Person();
        System.out.println(zs.age);
        System.out.println(zs.name);
    }
}

5.5、构造器的重载

当形参名字和属性名字重名的时候,程序有就近原则
在要表示对象的属性前加上this关键字,this表示当前对象;

java 复制代码
package com.msb1;

public class Person {
    //属性
    String name;
    int age;
    double height;

    //构造器:没有任何参数的构造器;空参构造器
    public Person() {

    }

    public Person(String name, int age, double height) {
        //当形参名字和属性名字重名的时候,程序有就近原则
        //在要表示对象的属性前加上this关键字,this表示当前对象;
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public Person(String a, int b) {
        name = a;
        age = b;
    }

    //方法
    public void eat() {
        System.out.println("吃饭");
    }
}

1、一般保证空构造器的存在,空构造器中一般不会进行属性的赋值操作。
2、一般我们会重载构造器,在重载的构造器中进行属性赋值操作。
3、在重载构造器以后,假如空构造器忘记写了,系统也不会给你分配默认的空构造器了,那么调用的时候就会出错。

java 复制代码
package com.msb1;

public class Test {
    public static void main(String[] args) {
        /*
        1、一般保证空构造器的存在,空构造器中一般不会进行属性的赋值操作。
        2、一般我们会重载构造器,在重载的构造器中进行属性赋值操作。
        3、在重载构造器以后,假如空构造器忘记写了,系统也不会给你分配默认的空构造器了,那么调用的时候就会出错。
         */
        Person zs = new Person("kobe", 20, 180);
        System.out.println(zs.name);
        System.out.println(zs.age);
        System.out.println(zs.height);
    }
}

6、this关键字用法:

1、在第一次遇到一个类的时候,对这个类进行加载,只加载一次。

2、创建对象,在堆中开辟空间。

3、对对象进行初始化操作,属性赋值都是默认的初始值。

4、new关键字调用构造器,执行构造器方法,对对象的属性进行重新赋值。

从上面的效果可以看到,this指代的就是当前对象。内存如下

6.1、this可以修饰属性

总结:

当属性名字和形参发生重名的时候,或者属性名字和局部变量重名的时候,都会发生就近原则,所以如果我要直接使用变量名字指的是离得近的形参或者局部变量。如果我想要表示属性的话,在前面要加上this.修饰

如果不发生重名问题的话,实际上你要是访问属性也可以省略this.不写

java 复制代码
package com.msb2;

public class Test {
    public static void main(String[] args) {
        //创建一个Person类的具体对象
        Person p = new Person(19,"kobe",180);
        p.eat();
    }
}
java 复制代码
package com.msb2;

public class Person {
    //属性
    int age;
    String name;
    double height;

    //空构造器
    public Person() {

    }

    //有参构造器
    public Person(int age, String name, double height) {
        this.age = age;
        this.name = name;
        this.height = height;
    }

    public void eat() {
        int age = 10;
        System.out.println(age);  // 就近原则10
        System.out.println(this.age); //这里指代的是属性的age
        System.out.println("吃饭");
    }

}

6.2、this可以修饰方法

总结:在同一个类中,方法可以互相调用,this.可以不写

java 复制代码
package com.msb2;

public class Test {
    public static void main(String[] args) {
        //创建一个Person类的具体对象
        Person p = new Person(19,"kobe",180);
        p.eat();
    }
}
java 复制代码
package com.msb2;

public class Person {
    //属性
    int age;
    String name;
    double height;

    //空构造器
    public Person() {

    }

    //有参构造器
    public Person(int age, String name, double height) {
        this.age = age;
        this.name = name;
        this.height = height;
    }

    public void eat() {
        int age = 10;
        System.out.println(age);  // 就近原则10
        System.out.println(this.age); //这里指代的是属性的age
        System.out.println("吃饭");
    }

    public void play() {
        this.play1();  //this可以省略不写
        System.out.println("吃饭");
        System.out.println("学习");
        System.out.println("睡觉");
    }

    public void play1() {
        System.out.println("学习");
    }


}

6.3、this可以修饰构造器

总结:同一个类中的构造器可以相互用this调用,注意,this修饰构造器必须放到第一行。

java 复制代码
package com.msb2;

public class Person {
    //属性
    int age;
    String name;
    double height;

    //空构造器
    public Person() {

    }

    //有参构造器
    public Person(int age, String name, double height) {
        this.age = age;
        this.name = name;
        this.height = height;
    }


    //有参构造器
    public Person(int age, String name) {
        this(age);
        this.name = name;
    }


    //有参构造器
    public Person(int age) {
        this.age = age;
    }

    public void eat() {
        int age = 10;
        System.out.println(age);  // 就近原则10
        System.out.println(this.age); //这里指代的是属性的age
        System.out.println("吃饭");
    }

    public void play() {
        this.play1();  //this可以省略不写
        System.out.println("吃饭");
        System.out.println("学习");
        System.out.println("睡觉");
    }

    public void play1() {
        System.out.println("学习");
    }


}

7、static

static可以修饰:属性、方法、代码块、内部类

7.1、static修饰属性

java 复制代码
package com.mas_static;

public class Test {
    //属性
    int id;
    static int sid;

    public static void main(String[] args) {
        //创建对象
        Test t1 = new Test();
        t1.id = 10;
        t1.sid = 10;

        Test t2 = new Test();
        t2.id = 20;
        t2.sid = 20;

        Test t3 = new Test();
        t3.id = 30;
        t3.sid = 30;

        //读取属性的值
        System.out.println(t1.id);
        System.out.println(t2.id);
        System.out.println(t3.id);

        System.out.println(t1.sid);
        System.out.println(t2.sid);
        System.out.println(t3.sid);

    }
}
7.1.1、static静态域示意图


一般官方的推荐访问方式:类名.属性名
static修饰总结:
1、在类加载的时候一起加载入方法区中的静态域中
2、先于对象存在
3、访问方式:对象名.属性名 类名.属性名

7.1.2、static修饰属性的应用创建

某些特定的数据,想要在内存中共享,只有一块------》这个情况下,使用static修饰。

java 复制代码
package com.mas_static;

public class MSBStudent {
    String name;
    int age;
    static String school;

    public static void main(String[] args) {
        MSBStudent.school = "qh";
        MSBStudent s1 = new MSBStudent();
        s1.name = "kobe";
        s1.age = 20;
//        s1.school = "qh";

        MSBStudent s2 = new MSBStudent();
        s2.name = "kobe";
        s2.age = 20;
//        s2.school = "qh";
        System.out.println(s2.school);
    }
}

属性:
静态属性(类变量、类属性)
非静态属性(实例变量、实例属性)

2、static修饰方法

1、static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都可以
2、在静态方法中不能访问非静态的属性
3、在静态方法中不能访问非静态的方法
4、在静态方法中,不能使用this关键字
5、非静态的方法可以使用对象名.方法名去调用
6、静态的方法可以使用 对象名.方法名去调用 也可以用类名.方法名去调用

java 复制代码
package com.mas_static;

public class Demo {
    int id;
    static int sid;

    public void a(){
        System.out.println("------a");
        System.out.println(id);
        System.out.println(sid);
    }

    //1、static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都可以
    public static void b(){
//        System.out.println(this.id); //在静态方法中,不能使用this关键字
//        a();     //在静态方法中不能访问非静态的方法
        System.out.println("------b");
//        System.out.println(id);  //在静态方法中不能访问非静态的属性
        System.out.println(sid);
    }

    public static void main(String[] args) {
        //非静态的方法可以使用对象名.方法名去调用
        Demo d =new Demo();
        d.a();
        //非静态的方法可以使用  对象名.方法名去调用  也可以用类名.方法名去调用
        Demo.b();
        d.b();
    }

}

8、代码块

代码块分为:普通块、构造块、静态块、同步块(多线程)

总结:

8.1、代码块执行顺序:

最先执行静态块,并且只在类加载的时候只执行一次,所以一般一九实战写项目:创建工厂、数据库初始化信息,一般用于执行全局性的初始化操作。

再执行构造块。(不常用)

再执行构造器。

再执行方法中的普通块。

java 复制代码
package com.msb3;

public class Test {
    //属性
    int a;
    static int sa;

    //方法
    public void a(){
        System.out.println("a");
        {
            //普通块限制了局部变量的作用范围
            System.out.println("这是普通块");
            int num = 1;
            System.out.println(num);
        }
    }
    //静态方法
    public static void b(){
        System.out.println("b");
    }

    //构造块
    {
        System.out.println("这是构造块");
    }
    //静态块
    static {
        //在静态块中只能访问静态方法,静态属性
        System.out.println("这是静态块");
        System.out.println(sa);
        b();
    }

    public Test(){
        System.out.println("这是空构造器");
    }

    //构造器
    public Test(int a){
        this.a=a;
    }

    public static void main(String[] args) {
        Test t= new Test();
        t.a();

        Test t1= new Test();
        t1.a();
    }


}
java 复制代码
这是静态块
0
b
这是构造块
这是空构造器
a
这是普通块
1
这是构造块
这是空构造器
a
这是普通块
1

Process finished with exit code 0

相关推荐
唐僧洗头爱飘柔95271 分钟前
(Go基础)变量与常量?字面量与变量的较量!
开发语言·后端·golang·go·go语言初上手
地平线开发者2 分钟前
征程 6 工具链性能分析与优化 2|模型性能优化建议
算法·自动驾驶
Duck Bro4 分钟前
数据结构:顺序表(动态顺序表)
c语言·数据结构·c++·学习·算法
·云扬·4 分钟前
Lambda 表达式详解
java·开发语言·笔记·学习·1024程序员节
linhhanpy12 分钟前
自制操作系统(九、操作系统完整实现)
c语言·开发语言·汇编·c++·操作系统·自制操作系统
ACALJJ3212 分钟前
STL整理
开发语言·c++
豆本-豆豆奶15 分钟前
最全面的Python重点知识汇总,建议收藏!
开发语言·数据库·python·oracle
Bosenya1218 分钟前
【信号处理】绘制IQ信号时域图、星座图、功率谱
开发语言·python·信号处理
monkey_meng18 分钟前
【Rust Crate之Actix Web(一)】
开发语言·后端·rust
AI原吾36 分钟前
探索PyAV:Python中的多媒体处理利器
开发语言·python·ai·pyav