欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

类和对象

程序员文章站 2024-03-16 11:07:16
...

一、对象与类

Java中的对象

  1. 定义:Java语言中的对象是对现实世界中对象的模拟,现实中的对象存在于现实生活中,Java语言中的对象存在于计算机内存中。Java语言中的对象又称为实例

  2. 属性和方法:Java中将现实对象中的信息称为属性(也叫全局变量),将现实对象中的功能称为方法。

Java中的类

  1. 定义:Java语言把一组对象中相同属性和方法抽象到一个Java源文件就形成了类。
  2. 定义类的步骤:定义类名——定义类的属性——定义类的方法。
public class  **类名** {  //属性
    属性1类型   属性1;
    属性2类型   属性2;
        …
    属性n类型   属性n;

    //方法
    方法1;
    方法2;
        …
    方法m;
}

类名的命名规则

  • 符合标识符命名规范;
  • 类名必须使用英文字母,首字母应大写,如Hello、People等。
  • 当类名由多个”单词”组合而成时,每个单词的首字母都要大写。如 Time、Game、Dog、DateUtil等。

//////////////////////////////////////////////////
举例
public class Student { // 可以在另一个类里面调用
    //定义属性
    String id;  //学号
    String name; //学生姓名
    String grade; //学生年级

    //定义读书方法
    public void readBook() {
        System.out.println(name + “正在读书……");
    }
    //定义写作业方法
    public void doHomework() {
        System.out.println(this.name + “正在写作业……");
    }
}

对象的创建与使用

  • 通过new关键字创建对象。创建对象又称实例化对象
  • Student student = new Student();

  • 使用“.”运算符访问对象的属性和方法。

  • student.属性 = 值;
    student.方法名();
public class TestStudent {
    public static void main(String[] args) {

        Student student = new Student();//创建李四学生类对象

        //new Student()为创建的对象,
        //Student为引用数据类型,student为引用类型变量
        //创建一个属于Student类型的对象,然后将该对象保存的内存地址赋值给student变量。

        student.id = "wl2014001";
        student.name = "李四";
        student.grade = "三年级";
        student.readBook();//调用学生读书方法
        student.doHomework();//调用学生写作业的方法
    }
}

类与对象

  • 类是创建对象的模板,确定对象将会拥有的属性和方法。
  • 类是对象的抽象化;对象是类的具体化。
  • 类是一种数据类型,是对象的数据类型(不同于int等基本类型:类具有方法)

面向对象与面向过程

  • 面向对象
    1、面向对象是一种编程思想,让对象成为类与类之间的“通信”的桥梁,通过对象使类之间形成有机的整体。

    2、面向对象编程语言以对象为中心,以消息为驱动,即程序=对象+消息

    3、消息——方法的调用:Java使用向方法传递参数的方式实现向方法发送信息;并通过返回值从方法中获取信息。
    类和对象


  • 面向过程
    面向过程编程语言则以过程为中心,以算法为驱动,即程序=算法+数据;
    类和对象

区别:

  • 面向对象是从宏观方面思考问题,而面向过程可以说是从细节处思考问题。
  • 在面向对象中,也存在面向过程。

二、方法与重载

方法的定义

  • 列表内容
    方法用于定义类的某种行为(或功能),其语法结构如下:
访问控制符 [修饰符] 返回值类型 方法名( [参数]——> 参数可有可无(等于这种形式))  {

           //方法体

}


----------
//举例
public void sayHello(){
    System.out.println("Hello");
}

protected final void show(int x){
        System.out.println(x);
}

private static int add(int x, int y){
    return x+y;
}

访问控制符

  • 方法中的访问控制符用于**限制**方法在其他**类中的使用范围**。
  • 访问控制符分为四种:public、protected、友好的和private。

将左边的public改成private,则该方法在右边类中无法被调用。
类和对象


修饰符

-static修饰符用于限制方法的调用方式:
- 其它常用方法修饰符有final和synchronized。

1、static修饰的方法可以直接使用类名调用也可以使用类创建的对象调用

类和对象
2、非static修饰的方法只能使用类创建的对象调用

类和对象


返回值类型

  • 如果方法没有返回值,需要用void表示。
void sayHello(){
    System.out.println("Hello");
}
  • 方法返回基本数据类型的数据,则返回值类型必须是返回数据所属的数据类型或者精度更高的数据类型(针对于数值类型的数据)
//参数值是int类型
boolean compare(int x, int y){
        return x>y;//返回布尔型
}

int add(int x, int y){
    return x+y;//返回int型
}

double subtraction(int x, int y){
    return x-y;//返回double型
}
  • 方法返回引用数据类型的数据,则返回值类型必须是返回数据所属的数据类型或者其父类

Object是所有返回值类型中范围最大的

public class Student{
    public Object getInto(String name,String adress ) {
            return name+"-"+adress;
        }

        public static void main(String[] args) {
            Student student = new Student();
            Object object = student.getInto("晓晓", "北京");
            System.out.println(object);
        }
}   
//返回数据的数据类型(Object)是返回数据所属数据类型(String)的父类。

  • 方法如果有返回值,则必须借助return关键字将数据返回;

方法名

  • 遵循标识符命名规则;首字母必须小写
  • 如果由多个单词组成,从第二个单词开始首字母必须大写
  • 方法名一般由一个动词或者动名词构成。
void printInfomation(){
        System.out.println("HelloWorld");
}

参数

  • 方法可以有多个参数,各个参数之间用逗号(,)间隔。
  • 方法的参数在整个方法内有效。
  • 方法参数前面的数据类型用于限制调用方法时所传具体数据的数据类型;
int multiplication(int x, int y){
        int result = x*y;
    return result;
}

动态参数

1、动态参数实质为数组
2、动态参数必须位于参数列表的最后
3、一个方法只能有一个动态参数

public void print(int a,int ... scores) {//定义一个动态参数
        System.out.println(scores[0]);//可以等价于一个数组,用它的下标即可//输出66
        for(int score:scores) {
            System.out.println(score);//当定义一个a时,此时a相当于原动态数组中的第一位,66,  55为a
        }
    }
    public static void main(String[] args) {
//      Computer array=new Computer();
//      array.print(55,66,77,88,99,100,44,33,65,76);等价于
        new Computer().print(55,66,77,88,99,100,44,33,65,76);
    }//输出66,66,77,88,99,100,44,33,65,76

方法重载

  • 定义:同一个类中有多个方法名相同但参数列表不同的方法,这种现象称为方法重载(overload)。
  • 1、参数的个数不同
    2、参数的对应类型不同
  • 注意:
    1、参数列表不同并不包含参数名不同,也就是说如果方法名相同,方法中参数个数和类型相同,只是参数名不同,这样也不能称之为方法重载。

    2、方法中其它构成部分不参与比较:访问控制符、修饰符、返回值类型。

  • 调用:一个类中有多个同名方法(构造方法或普通方法),在调用这些方法时,到底调用哪个方法取决于调用方法时传入的参数的数据类型和个数

public class Teacher {

    public static void print(int age, String name) {
        System.out.println(age + "," + name);
    }

    public static void print(String name, int age) {
        System.out.println(name + "," + age);
    }

    public static void main(String[] args) {
        print(33, “王小红”);// 依次传入int类型和String类型数据,所以调用第一个方法
        print("王小红", 33);//依次传入String类型和int类型数据,所以调用第二个方法
    }
}

注意

  • 多个方法不能相互嵌套定义!
  • 不能在方法外部或者类里直接写程序逻辑代码!
  • 类里只能写属性方法和代码块
  • 方法不能返回多个值!
  • 对变量的操作只能在方法或代码块中进行,不能直接在类中进行。

三、代码块

Java中代码块分为静态代码块非静态代码块

静态代码块

静态代码块只在类加载时执行一次

public class Test {

    static{
        System.out.println("静态代码块");
    }

    public static void main(String[] args) {

    }
}

非静态代码块

非静态代码块每次创建对象时都会执行

public class Test {

    {
        System.out.println("非静态代码块");
    }

    public static void main(String[] args) {
        new Test();
        new Test();
    }
}
public class Test {

    {
        System.out.println("非静态代码块");
    }

    static{
        System.out.println("静态代码块");
    }

    public static void main(String[] args) {
        new Test();
        new Test();
    }
}

//输出
//静态代码块
//非静态代码块
//非静态代码块



四、全局变量和局部变量

变量的分类

类和对象

全局(成员)变量

  • 直接在类中声明的变量成员变量(又称全局变量)实例变量、类变量、常量都是属于成员变量

  • 分类:
    1、一种是被static关键字修饰的变量,叫类变量或者静态变量
    2、没有static修饰,为实例变量*。

  • 如果未对成员变量设置初始值,则系统会根据成员变量的类型自动分配初始值:int分配初始值0、boolean分配初始值false,而自定义类型则分配初始值null。

  • 成员变量定义后,其作用域是其所在的整个类

  • 成员变量的定义没有先后顺序,但是最好将成员变量的定义集中在类的顶部。

局部变量

  • 定义:方法中的参数、方法中定义的变量和代码块中定义的变量统称为局部变量。
  • 作用范围:从定义的位置开始到其所在语句块结束
    {   //代码块中的局部变量
        int number=6;//局部变量没有默认值
        System.out.println(number);
    }

    public void ptint(int price) {

        if(price==6) {
            String student="小娃";
            System.out.println(student);
        }//到大括号if这儿结束
        System.out.println(price);
        //System.out.println(student);出现错误      
    }

五、构造方法

含义

  1. 构造方法负责初始化类中的实例变量
  2. 构造方法是一种特殊的方法,这种方法必须满足以下语法规则:
    构造方法必须与类名相同;不包含返回值类型描述部分。
  3. 构造方法不能有static和final关键字修饰。

使用

public class Teacher {

    int age; // 年龄
    String name; // 姓名
    String position; // 职位
    String education; // 学历

    public String introduction() {
        return "大家好!我是" + name + ",我今年" + age + "岁,学历" + education + ",目前职位是" + position;
    }
}

使用new关键字调用构造方法,即构造方法在创建对象(也称对象实例化)时被调用。

public class  TeacherTest {
    public static void main(String[ ] args) {
        Teacher  teacher = new Teacher(); //创建Teacher对象
        //new Teacher()-由于Teacher类没有显式构造方法,这时Teacher类就会有一个默认的无参构造方法。
    }
}

显示构造方法

  • 创建类时,如果没有显式定义构造方法,则该类会存在一个默认的无参构造方法;

  • 可以在类中声明一个或多个有参构造方法,但每个构造方法在参数个数或参数数据类型上要有所差别:可以认为是重载

public class Teacher {

    int age; // 年龄
    String name; // 姓名
    String position; // 职位

    public Teacher(int age){
        this.age=age;
    }

    public Teacher(String name){
        this.name=name;
    }

    public Teacher(int age,String name){
        this.age=age;
        this.name=name;
    }

    public String introduction() {
        return "大家好!我是" + name + ",我今年" + age + "岁,学历" + education + ",目前职位是" + position;
    }
}
  • 如果类中存在显式构造方法则默认的无参构造方法将不复存在,除非显式定义无参构造方法
public class Student {

     String name;
     int age;

    public Student(){

    }//若无参构造方法不加上,创建对象时会出错
    public Student(int age,String name) {
        this.name=name;
        this.age=age;
    }

    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student);
    }
}
  • 类中可以有多个构造方法,构造方法之间可以通过this实现调用,但必须将调用构造函数代码写在有效代码的第一行
  • 普通方法不能使用this调用类中构造方法:构造方法不能在普通方法中调用
public class Student {

     String name;
     int age;

    public Student(String name){
        this.name=name;
    }
    public Student(int age,String name) {
        this(name);//写在第一行,这个this指的是调用上面的Student
        this.age=age;
    }
}

关键字this

  • this代表对当前对象的一个引用 【this指代一个对象】
  • this关键字用于调用属性、方法及本类中构造方法
  • 关键字this不能在被static修改的方法和代码块中使用【因为不能保证调用静态方法的一定是对象】
package com.lq.tool;

public class Student {

    String name;

    void doHomework(){
        System.out.println(this.name+"正在做作业.......");
    }

    void speak(){
        name = "晓晓";
        new Student().doHomework();//调用doHomework()中的name
        this.doHomework();//调用当前对象的name
        System.out.println(name+"正在说话......");
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.speak();
    }
}
//运行结果:
//null正在做作业.......
//晓晓正在做作业.......
//晓晓正在说话......
String name;

    void doHomework(){
        System.out.println(this.name+"正在做作业.......");
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.name="王五";
        student.doHomework();
    }
//运行结果:王五正在做作业......
package com.lq.tool;

public class Student {

String name;

    void doHomework(){
        System.out.println(this.name+"正在做作业.......");
        name="刘颖";//全局变量赋值
        //如果将其改为String name="刘颖";
    }

    void speak(){
        System.out.println(name+"正在说话......");
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.doHomework();
        student.speak();
    }

}
运行结果:
1、name="刘颖";//为全局变量赋值
null正在做作业.......
刘颖正在说话......

2String name="刘颖";//此时为局部变量,到语句结束时停止作用。
null正在做作业.......
null正在说话......
package com.lq.tool;

public class Student {

    int age;
    String name;

    public Student(int age) {
        this.age = age;
    }
    public Student(String name) {
        this.name = name;
    }
    public Student(int age, String name) {
        this(age);
        new Student(name);//这个对象指向上面定义有name的构造方法
        System.out.println(age+"+"+this.name);//此时输出12+null

        System.out.println(age+"+"+name);//此时输出12+王五
        //输出的name指的是当前构造方法中的参数

        this.name=name;
        System.out.println(age+"+"+this.name);//此时输出12+王五
        System.out.println(age+"+"+name);//此时输出12+王五

    }
    public static void main(String[] args) {
        new Student(12, "王五");
    }

}

六、 对象初始化过程

package com.lq.tool;

public class Student {

    String name="张三";

    //执行非静态代码块时,对象已经创建,否则this.name会出现错误
    {
        System.out.println("非静态代码块"+this.name);
    }

    //调用构造函数时,对象已经存在了,否则this.name会出现错误
    public Student(String name){
        this.name = name;
        System.out.println("构造方法"+name);
    }

    //程序运行结果先输出张三,然后输出李四,
    //可见一定先调用非静态代码块,再调用构造函数,
    //并且调用非静态代码块时所创建对象的实例属性值为初始化值,或者是默认值(如果没有初始化)
    public static void main(String[] args) {
        Student student = new Student("李四");
    }

}


  • 用new创建并初始化对象步骤:

1、给对象的实例变量(非“常量”)分配内存空间,默认初始化成员变量;

2、成员变量声明时的初始化;

3、初始化块初始化(又称为构造代码块或非静态代码块);

4、构造方法初始化

package com.lq.tool;

public class Student {

    String stuName = "";
    int stuAge= -1;
    int stuSex= -1;
    int stuGrade= -1;

    //对象的初始化块初始化
    {
        System.out.println("使用初始化块初始化");
        this.stuName="雷静";
        this.stuAge=18;
        this.stuSex=2;
        this.stuGrade=4;
    }

    //无参构造方法
    public Student() {
        System.out.println("使用无参构造函数初始化");
    }

    //有参构造方法,用户初始化对象的成员变量
    public Student(String name, int age, int sex, int grade) {
        System.out.println("使用有参构造函数初始化");
        this.stuName = name;
        this.stuAge = age;
        this.stuSex = sex;
        this.stuGrade = grade;
    }
}
package com.lq.tool;

public class TestStudent{

    public static void main(String[] args) {
        //构造方法初始化成员变量在对吸纳该初始化块初始化之后
        Student temp = new Student("王云",22,1,4);
        System.out.println(temp.stuName+"正在读大学"+temp.stuGrade+"年级");
    }
}
//运行结果
使用初始化块初始化
使用有参构造函数初始化
王云正在读大学4年级

对象初始化过程

  1. 给对象的实例变量分配空间,默认初始化成员变量
  2. 成员变量声明时的初始化
  3. 初始化块初始化
  4. 构造方法初始化