深入理解类和对象(2) —— Java SE

深入理解类和对象(2) —— Java SE,第1张

                      

目录

🐲 1. static 成员

🦄 1.1 static的作用

 🦄 1.2 static修饰成员变量

🦄 1.3 static修饰成员方法

🐲 2.代码块

🦄2.1 普通代码块

🦄2.2 实例代码块(构造代码块)

🦄2.3 静态代码块

🐲 3. 理解内部类

🦄 3.1 内部类的分类

🦄 3.2 实例内部类

🦄 3.3 静态内部类

🦄 3.4 本地内部类 

🐲 4.打印对象


🐲 1. static 成员 🦄 1.1 static的作用

先定义一个学生类

public class Student {
    public String name;
    public String gender;
    public int age;
    public double score;

    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }
    public void PrintStudent(){
        System.out.println(name + " " + gender + " " + age + " " + score);
    }

    public static void main(String[] args) {
        Student s1 = new Student("Zhang san","男",20,4.0);
        Student s2 = new Student("li si","男",21,3.9);
        Student s3 = new Student("Wing wu","男",22,2.9);
        s1.PrintStudent();
        s2.PrintStudent();
        s3.PrintStudent();
    }
}

🟦在Student类中定义的成员变量,每个对象中都会包含一份实例变量 ,也就是用来描述三个学生

🟪假如说这三个学生是一个班的,再来一个成员变量,用来表示这个班级,然后将这个成员变量对所有学生共享。

这就要用到,static来修饰成员变量了,

🟧被static修饰的成员叫静态成员,或者叫类成员,它对所有对象是共享的。

 🦄 1.2 static修饰成员变量

🟥static 修饰的成员变量,叫做静态成员变量。

🟦作用是 这个静态成员变量是所有对象共享的,不是属于单独某个具体对象。

 访问有两种方式

⚜️第一种 通过对象访问(不建议),

因为静态成员变量是所有对象共享的

 ⚜️第二种 直接通过类名来访问(建议使用这种)

好了,就是上面两种方法可以访问静态成员变量 ,

⚜️需要额外注意的两点是:

    (1)类变量存储在方法区中

    (2)生命周期同类一样

下面看一下全部代码

public class Student {
    //普通成员变量
    public String name;
    public String gender;
    public int age;
    public double score;
    //静态成员变量,不属于对象
    //被Static修饰就变成了静态成员,都可以使用这个,变成共享的
    public static String classRoom = "gao yi 13 ban";

    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }
    public void PrintStudent(){
        System.out.println(name + " " + gender + " " + age + " " + score);
    }

    public static void main1(String[] args) {
        //静态成员可以直接使用类名来访问
        Student s1 = new Student("Zhang san","男",20,4.0);
        Student s2 = new Student("li si","男",21,3.9);
        Student s3 = new Student("Wing wu","男",22,2.9);
        //不建议通过对象的引用去访问
        System.out.println(s1.classRoom);
        System.out.println(s2.classRoom);
        System.out.println(s3.classRoom);
        //建议最好通过类名去访问
        System.out.println(Student.classRoom);
        //只是通过类名点出来的
        s1.PrintStudent();
        s2.PrintStudent();
        s3.PrintStudent();
    }
}
🦄 1.3 static修饰成员方法

🟥static修饰成员方法,叫做静态成员方法,

🟦 静态成员方法是类的方法,不是某个对象所特有的,

      静态成员一般是通过静态方法来访问

⚜️那么如何访问静态方法呢

 因为静态方法是类方法,所以可以直接访问

class Student {
    public String name;
    public double score;
    public int age;
    public static  String classRoom = "gao yi 13 ban" ;

    public Student(String name, double score, int age) {
        this.name = name;
        this.score = score;
        this.age = age;
    }

    public static void staticFunc(Student student) {
        System.out.println("这是一个静态的方法!也是类方法");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student.staticFunc();
    }
}

⚜️先思考一下,如何在静态方法中,访问非静态的成员变量

首先,因为静态方法不需要对象,所以直接访问在静态方法访问非静态的成员变量,是不可行的。

其次,如果必须要访问,我们应该考虑的是,如何通过对象调用,使静态方法中,可以访问非静态的成员变量

有两种方法:

🟥第一种,既然要访问非静态成员变量,而静态方法又不需要对象,那么给静态方法中调用对象,不就可以了 

🟪 第二种,也可以给静态方法个参数(建议使用这种)

 ⚜️再思考最后一个问题,静态方法中,可以调用非静态的方法吗?

🟪不可以直接调用,因为非静态方法有this参数,(this表示当前对象的引用)在静态方法中调用时候无法传递this引用

总结一下,

🟥静态方法是类方法,不属于某个具体的对象

🟧静态方法中,不能直接访问非静态的变量,

🟦静态方法中,也不能调用非静态的方法


🐲 2.代码块

使用{ }定义的一段代码叫代码块,根据代码块定义的位置和关键字,分为了4种

普通代码块,构造代码块,静态代码块,同步代码块,我们这里先讲解前3个代码块

🦄2.1 普通代码块

🟪定义在方法中的代码块,叫普通代码块

    public static void main(String[] args) {
        {
            //1.普通代码块,直接用{}定义
            int x = 10;
            System.out.println("x1="+x);
        }
        int x = 100;
        System.out.println("x2="+x);
    }

🦄2.2 实例代码块(构造代码块)

🟪定义在类中的代码块(前面没有修饰符)

🟦用于初始化实例成员变量

class Student{
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom;

    public Student(){
        System.out.println("I am Student!");
    }
     //实例代码块
    {
        this.name = "zhang san";
        this.age = 24;
        this.score = 45.6;
        System.out.println("I am Instance!");
    }
    public void Show(){
        System.out.println("name" + name + "age" + age + "score" + score);
    }
}
public class Test01 {
public static void main(String[] args) {
    //2.构造代码块:定义在类中的代码块,也叫实例代码块
    //一般用于初始化实例成员变量
    Student  student = new Student();
    student.Show();
}

}

🦄2.3 静态代码块

🟪使用static定义的代码块

🟩用于初始化静态成员变量

class Student{
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom;

    static {
        classRoom = "gao er 13 ban ";
        System.out.println("I am static");
    }
    public Student(){
        System.out.println("I am Student!");
    }
}
public class Test01 {
public static void main(String[] args) {
    //3.静态代码块:用于初始化静态成员变量
    Student s1 = new Student();
    Student s2 = new Student();
}
}

注意:

🟥(1)静态代码块不管生成有多少个对象,只会执行一次

🟧(2)静态成员变量是类的属性,因此是在JVM加载类是开辟空间进行初始化

🟦(3)实例代码块只有在创建对象时才会执行

⚜️下面思考一个问题,

⚜️如果一个类中,有构造方法,实例代码块,静态代码块,执行的顺序是怎么样的

先执行静态代码块(如果有多个静态代码块,看定义顺序执行)(静态代码块只会执行一次),再执行实例代码块,最后执行构造方法


🐲 3. 理解内部类

 如果内部类的完整结构只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。

🟪将一个类定义在另一个类或者一个方法的内部,

🟥比如 InnerClass{}就是内部类,OuterClass{}就是外部类。

🟩内部类和外部类共用一个java源文件,经过编译后,内部类会形成单独的字节码文件

🦄 3.1 内部类的分类

在外部类中,内部类定义位置与外部类成员所处的位置相同,所以也叫做成员内部类

实例内部类                静态内部类  (本篇先介绍前两个)

本地内部类                匿名内部类 

🦄 3.2 实例内部类

⚜️实例内部类就是没有static修饰的成员内部类

下面看这个例子 ,可以很清楚的看到实例内部类

class  OuterClass{

    public int date1 = 1;
    private int date2 = 2;
    public static int data3 = 3;
    //实例内部类,没有别static修饰
    class InnerClass{
        public int data4 = 4;
        private int data5 = 5;
        public static final int data3 = 6;

        public InnerClass(){
            System.out.println("实例内部类的构造方法!");
        }
        public void innerFunc(){
            System.out.println("实例内部类的普通方法!");
            System.out.println(date1);
            System.out.println(date2);
            System.out.println(data3);
        }
    }
}
public class Test01 {
    public static void main(String[] args) {
        OuterClass out = new OuterClass();
        OuterClass.InnerClass innerClass = out.new InnerClass();
        innerClass.innerFunc();
    }
}

通过上面代码,可以清楚知道 

🟪在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员

⚜️ 1.下面思考一下,如果外部类和实例内部类具有相同名称的成员时,先访问谁,

      并且如果要访问外部类同名成员时,如何访问?

       那如果是同名的静态成员呢,如何访问?

🟦同名时,优先访问的是内部类自己的,

🟧要访问外部类同名成员时,按这样格式访问

外部类名称.this.同名成员名字

🟪外部类类名.同名成员名字

⚜️ 2.实例内部类中,不能直接定义静态的成员变量,如果必须要定义,如何做?

         实例内部类中,可以定义静态方法吗?

🟪如果必须要定义,那么这个静态变量成员就应该被final所修饰

 不可以,定义静态方法

⚜️ 3.如何实例化,实例内部类

有两种方法:

🟦外部类类名.内部类  变量=外部类引用,new  内部类();

🟩外部类类名.内部类  变量=new 外部类().new 内部类(); 


🦄 3.3 静态内部类

🟪被static修饰的内部成员类称为静态内部类。

 下面看这个例子 ,可以很清楚的看到静态内部类

class OuterClass1{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;

    static class InnerClass{
        public int data4 =4;
        private int data5= 5;
        public static int data6 =6;

        public InnerClass(){
            System.out.println("静态内部类的构造方法!");
        }
        public void test(){
            System.out.println("test方法执行了!");
    
            System.out.println(data4);
            System.out.println(data3);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}
public class Test02 {
    public static void main(String[] args) {
        OuterClass1.InnerClass innerClass = new OuterClass1.InnerClass();
        innerClass.test();
    }
}

通过上面代码,可以清楚知道 

🟧 1. 在静态内部类中只能访问外部类中的静态成员 🟪 2. 创建静态内部类对象时,不需要先创建外部类对象

 ⚜️ 1.下面思考一下,如何拿到静态内部类中的对象

🟩外部类类名.内部类类名 变量 = new 外部类类名.内部类类名。

⚜️ 2.不能在静态内部类当中,直接访问外部类非静态的数据成员,那么怎么样才能访问到外部类非静态的数据成员?

有两种方法,都是靠对象来引用的

🟪第一种直接在内部类当中引用对象

🟧 第二种 通过参数引用


🦄 3.4 本地内部类 

定义在外部类的方法体或者{}中,本地内部类只能在其定义的位置使用,这里简单了解一下

public class Test03 {
    public static void func() {
        class A{
            public void test(){
                System.out.println(100);
            }
        }
        A a = new A();
        a.test();
    }
    public static void main(String[] args) {
        func();
    }
}
🟧只能在该方法体内部使用,其他位置都不能用

🐲 4.打印对象
public class Test03 {
class Person{
        public String name;
        public int age;
    
    @Override//注解:注释【代表这个方法是重写父类的】+解释
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test03{
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);
    }
}

以后重写toSring可以借助IDea功能来快速写出


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/920831.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存