c面向对象基础2-类和对象

2023-10-18 22:04:49 浏览数 (2)

类和对象

(1)类(class)

  • 我们叫做class,可以看做是一个模版,或者图纸,系统根据类的定义来造出对象。
  • 是抽象总结的结果

(2)对象

  • 我们叫做Object,instance(实例)。以后我们说某个类的对象,某个类的实例。是一样的意思。

(3)总结

  1. 对象是具体的事物;类是对对象的抽象;
  2. 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
  3. 类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

(4)第一个类

示例:

代码语言:javascript复制
// 每一个源文件必须有且只有一个public class,并且类名和文件名保持一致!public class Car { 
}
class Tyre { // 一个Java文件可以同时定义多个class
}
class Engine {
}
class Seat {
}
  • 上面的类定义好后,没有任何的其他信息,就跟我们拿到一张张图纸,但是纸上没有任何信息,这是一个空类,没有任何实际意义。
  • 所以,我们需要定义类的具体信息。对于一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor。
  • 这三种成员都可以定义零个或多个。

示例:

代码语言:javascript复制
public class Student {
    //属性(成员变量)
    int id;
    String sname;
    int age;  
    //方法
    void study(){
        System.out.println("我正在学习!");
    }  
    //构造方法
   Student(){
   }
}

(5)属性

  • 详细见第二节Java代码构成总结的变量-成员变量

(6)方法

  • 详细见第二节Java代码构成总结的方法

(7)构造方法

  • 构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应与类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。
  • 对象并不是完全由构造器负责创建。创建一个对象分为如下四步:
    1. 分配对象空间,并将对象成员变量初始化为0或空
    2. 执行属性值的显式初始化
    3. 执行构造方法
    4. 返回对象的地址给相关的变量

声明格式:

代码语言:javascript复制
[修饰符] 类名(形参列表){
    //n条语句
}
  1. 通过new关键字调用!!
  2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
  3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!
  4. 构造器的方法名必须和类名一致!

(8)构造方法的重载

  • 构造方法也是方法,只不过有特殊的作用而已。与普通方法一样,构造方法也可以重载。
  • 如果方法构造中形参名与属性名相同时,需要使用this关键字区分属性与形参。如示例所示:this.id 表示属性id;id表示形参id

示例:

代码语言:javascript复制
public class User {
    int id; // id
    String name; // 账户名
    String pwd; // 密码
    public User() {
 
    }
    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
    public static void main(String[] args) {
        User u1 = new User();
        User u2 = new User(101, "张三");
        User u3 = new User(100, "李四", "123456");     
    }
}

(9)this 关键字

  • this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。
  • this最常的用法:
    1. 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。

    示例: public class User { int id; //id String name; //账户名 String pwd; //密码 public User() { } public User(int id, String name) { System.out.println("正在初始化已经创建好的对象:" this); this.id = id; //不写this,无法区分局部变量id和成员变量id this.name = name; } public void login(){ System.out.println(this.name ",要登录!"); //不写this效果一样 } public static void main(String[] args) { User u3 = new User(101,"张三"); System.out.println("打印张三对象:" u3); u3.login(); } }

    1. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。

    示例: public class TestThis { int a, b, c; TestThis() { System.out.println("正要初始化一个Hello对象"); } TestThis(int a, int b) { // TestThis(); //这样是无法调用构造方法的! this(); // 调用无参的构造方法,并且必须位于第一行! a = a;// 这里都是指的局部变量而不是成员变量// 这样就区分了成员变量和局部变量. 这种情况占了this使用情况大多数! this.a = a; this.b = b; } TestThis(int a, int b, int c) { this(a, b); // 调用带参的构造方法,并且必须位于第一行! this.c = c; } void sing() { } void eat() { this.sing(); // 调用本类中的sing(); System.out.println("你妈妈喊你回家吃饭!"); } public static void main(String[] args) { TestThis hi = new TestThis(2, 3); hi.eat(); } }

    1. this不能用于static方法中。

(10)static 关键字

  • 在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。
  • 特点:
    1. 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
    2. 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!
    3. 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
    4. 在static方法中不可直接访问非static的成员。
  • 核心要点:
    1. static修饰的成员变量和方法,从属于类。
    2. 普通变量和方法从属于对象的。

示例:

代码语言:javascript复制
public class User2 {
    int id; // id
    String name; // 账户名
    String pwd; // 密码
     
    static String company = "京东"; // 公司名称
     
     
    public User2(int id, String name) {
        this.id = id;
        this.name = name;
    }
     
    public void login() {
        printCompany();
        System.out.println(company); 
        System.out.println("登录:"   name);
    }
     
    public static void printCompany() {
//         login();//调用非静态成员,编译就会报错
        System.out.println(company);
    }
     
    public static void main(String[] args) {
        User2 u = new User2(101, "张三");
        User2.printCompany();
        User2.company = "阿里";
        User2.printCompany();
    }
}

(11)静态初始化块

  • 构造方法用于对象的初始化!
  • 静态初始化块,用于类的初始化操作!
  • 在静态初始化块中不能直接访问非static成员。
  • 静态初始化块执行顺序(继承):上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止
  • 在构造器之前执行,先加载类,在执行构造对象

示例:

代码语言:javascript复制
public class User3 {
    int id;        //id
    String name;   //账户名
    String pwd;   //密码
    static String company; //公司名称
    
    static {
        System.out.println("执行类的初始化工作");
        company = "东软";
        printCompany();
    }  
    
    public static void printCompany(){
        System.out.println(company);
    }  
    public static void main(String[] args) {
        User3  u3 = new User3();
        //User3  u3 = null;
    }
}

(12)对象的内存分析

  • Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。
  • 栈的特点如下:
    1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
    2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
    3. 栈属于线程私有,不能实现线程间的共享!
    4. 栈的存储特性是“先进后出,后进先出”
    5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!
  • 堆的特点如下:
    1. 堆用于存储创建好的对象和数组(数组也是对象)
    2. JVM只有一个堆,被所有线程共享
    3. 堆是一个不连续的内存空间,分配灵活,速度慢!
  • 方法区(又叫静态区)特点如下:
    1. JVM只有一个方法区,被所有线程共享!
    2. 方法区实际也是堆,只是用于存储类、常量相关的信息!
    3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、静态方法、字符串常量等)

(13) 参数传值机制

  • Java中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。
  • 基本数据类型参数的传值:传递的是值的副本。 副本改变不会影响原件。
  • 引用类型参数的传值:传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”。

示例:

代码语言:javascript复制
public class User4 {
    int id;        //id
    String name;   //账户名
    String pwd;   //密码
       
    public User4(int id, String name) {
        this.id = id;
        this.name = name;
    }
      
    public   void   testParameterTransfer01(User4  u){
        u.name="高手";
    }
     
    public   void   testParameterTransfer02(User4  u){
        u  =  new  User4(200,"高手B");
    }
      
    public static void main(String[] args) {
        User4   u1  =  new User4(100, "高手A");
         
        u1.testParameterTransfer01(u1); 
        System.out.println(u1.name);
 
        u1.testParameterTransfer02(u1);
        System.out.println(u1.name);
    }
}

邀请人:玖叁叁

0 人点赞