面向对象

介绍

面向对象三大特征:

  1. 封装

  2. 继承

  3. 多态

一个类里面能写五类东西:

  1. 成员变量(代表属性,一般是名词)

  2. 成员方法(代表行为,一般是动词)

  3. 构造方法

  4. 代码块

  5. 内部类

类分为三种:

  1. JavaBean 类

  2. 测试类

  3. 工具类

类名采用大驼峰命名规则。

一个 Java 源文件可以写多个类(实际开发不会这么做,实际开发中一般一个源文件只写一个类),但是最多只能有一个 public 类,如果有一个 public 类,则该 public 类的类名必须和文件名相同。

用来描述某一个事物的类称为 Javabean 类,Javabean 类中不写 main() 方法,可以写成员变量和成员方法,其中所有的成员变量都必须是私有的,同时提供对应的公有的 getter() 和 setter() 方法。除了 getter() 和 setter() 方法,如果 JavaBean 类中还有其他成员方法,也需要一并写出。

访问修饰符(access modifier)用于控制程序的其他部分对其所修饰部分的访问权限。
private 访问修饰符和 public 访问修饰符都可以修饰成员,例如成员变量和成员方法等,用 private 修饰的成员只能在本类中访问,用 public 修饰的成员可以在所有类中访问。
用 public 或 private 修饰成员变量时不影响它的默认值。

带 main() 方法的类称为测试类,可以在测试类中创建 Javabean 类的对象并赋值调用。

工具类只提供一些功能用来做某件事,所以也不会定义 main() 方法,为了方便调用,工具类中的方法都是静态的,即用 static 修饰的,这样就不需要定义对象,直接使用类名来调用。比如 Math 类:

public class Test {
    public static void main(String[] args) {
        int myAbs = Math.abs(-10);
        System.out.println(myAbs);  // 10
    }
}

程序示例:

先写一个 JavaBean 类,再写一个这个 JavaBean 类的测试类。

JavaBean 类:

public class Phone {
    private int price;
    private String branch;

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getBranch() {
        return branch;
    }

    public void setBranch(String branch) {
        this.branch = branch;
    }

    // 其他成员方法
    public void call() {
        System.out.println("手机可以用来打电话。");
    }
}

测试类:

public class PhoneTest {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.setBranch("苹果");
        phone.setPrice(1000);
        System.out.println("品牌为:" + phone.getBranch());
        System.out.println("价格为:" + phone.getPrice());
        // 调用其他成员方法
        phone.call();
    }
}

测试类的执行结果:

品牌为:苹果
价格为:1000
手机可以用来打电话。

在 JavaBean 类中定义成员变量时,一般都不会给成员变量赋一个初始值,因为各个对象的成员变量的值都可能不相等,而且当不给成员变量赋初始值时,成员变量会有一个默认值。

默认值:

  • 基本数据类型:

    • byte、short、int、long:0

    • float、double:0.0

    • char:空格

    • boolean:false

  • 引用类型:

    • String、类、接口、数组:null

程序示例:

JavaBean 类:

public class DefaultValue {
    private byte b;
    private short s;
    private int i;
    private long L;
    private char c;
    private boolean boo;
    private float f;
    private double d;
    private String st;

    public byte getB() {
        return b;
    }

    public void setB(byte b) {
        this.b = b;
    }

    public short getS() {
        return s;
    }

    public void setS(short s) {
        this.s = s;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public long getL() {
        return L;
    }

    public void setL(long l) {
        L = l;
    }

    public char getC() {
        return c;
    }

    public void setC(char c) {
        this.c = c;
    }

    public boolean getBoo() {
        return boo;
    }

    public void setBoo(boolean boo) {
        this.boo = boo;
    }

    public float getF() {
        return f;
    }

    public void setF(float f) {
        this.f = f;
    }

    public double getD() {
        return d;
    }

    public void setD(double d) {
        this.d = d;
    }

    public String getSt() {
        return st;
    }

    public void setSt(String st) {
        this.st = st;
    }
}

测试类:

public class DefaultValueTest {
    public static void main(String[] args) {
        DefaultValue defaultValue = new DefaultValue();
        System.out.println(defaultValue.getB());
        System.out.println(defaultValue.getS());
        System.out.println(defaultValue.getI());
        System.out.println(defaultValue.getL());
        System.out.println(defaultValue.getC());
        System.out.println(defaultValue.getBoo());
        System.out.println(defaultValue.getF());
        System.out.println(defaultValue.getD());
        System.out.println(defaultValue.getSt());
    }
}

测试类执行结果:

0
0
0
0
 
false
0.0
0.0
null

封装

Javabean 类的成员变量被定义为了私有, 即被 private 修饰, 同时提供对应的公有的 getter() 和 setter() 方法。外界对成员变量的操作 (包括赋值和获取值等等) 都应该通过 getter() 和 setter() 方法进行,而不是直接操作这些私有的成员变量。这便是封装。

this

this 的作用

定义在方法里面的变量叫做局部变量(包括定义在方法头内的形参变量),定义在方法外(当然,一定是在类里面)的变量叫做成员变量

如果局部变量和成员变量同名,则在方法内局部变量覆盖成员变量,这叫做遵循就近原则。

如果不希望让局部变量覆盖成员变量,即希望在方法中可以访问到与局部变量同名的成员变量,就需要在访问成员变量时在成员变量前面加上关键字 this。

this 的作用:区分成员变量和局部变量。
this 的本质:代表了调用者(即某一个对象)的地址值。

this 的内存原理

程序示例:

JavaBean 类:

public class Student {
    private int age;

    public void method() {
        int age = 10;
        System.out.println(age);
        System.out.println(this.age);
    }
}

测试类:

public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student();
        student.method();
    }
}

上述程序的内存原理:


图 1

程序示例:

JavaBean 类:

public class Girl {
    private int age;// 成员变量

    public int getAge() {
        return age;  // 返回成员变量
    }

    public int getAgeCovered() {
        int age = 18;  // 局部变量
        return age;  // 遵循就近原则,返回局部变量
    }

    public int getAgeNoCovered() {
        int age = 18;  // 局部变量
        return this.age;  // 返回成员变量
    }
}

测试类:

public class GirlTest {
    public static void main(String[] args) {
        Girl girl = new Girl();
        int ageCovered = girl.getAgeCovered();
        int ageNoCovered = girl.getAgeNoCovered();
        System.out.println("被覆盖:" + ageCovered);
        System.out.println("没有被覆盖:" + ageNoCovered);
    }
}

测试类执行结果:

被覆盖:18
没有被覆盖:0

程序示例:

JavaBean 类:

public class Boy {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String n) {
        name = n;  // 如果成员变量和局部变量不同名,则 this 写或不写效果都一样,都是访问成员变量
    }

    public void setNameCovered(String name) {
        name = name;  // 等号左侧实际访问的是形参 name,所以没有对成员变量 name 进行赋值
    }

    public void setNameNoCovered(String name) {
        this.name = name; // 等号左侧实际访问的是成员变量 name
    }
}

测试类:

public class BoyTest {
    public static void main(String[] args) {
        Boy boy = new Boy();
        System.out.println(boy.getName());
        boy.setNameCovered("小明");
        System.out.println(boy.getName());
        boy.setNameNoCovered("小李");
        System.out.println(boy.getName());
    }
}

测试类执行结果:

null
null
小李

构造方法

构造方法也叫构造器或构造函数,作用是在创建对象时给成员变量进行初始化(即赋值)。

构造方法的格式:

public class Student {
    // 构造方法
    修饰符 类名(参数) {
        方法体;
    }
}

注意:

方法名必须和类名完全相同。
没有返回值类型,连 void 也不能有。
没有返回值,不能有 return 语句,即便是 return; 也不能有。

使用空参构造方法时成员变量被初始化为默认值。空参构造方法的方法体都是空的,什么都不写。

可以自定义带参构造方法,在方法体内可以给成员变量赋值。带参构造的形参不一定是全部成员变量,可能只有部分成员变量,在构造方法体内只给部分成员变量赋值。

构造方法在创建对象时由虚拟机自动调用,不能手动调用构造方法。每创建一次对象,虚拟机就会自动调用一次构造方法。

如果没有自定义的构造方法,那么虚拟机会自动添加一个空参构造方法,所以此时空参构造方法也不需要我们自己手动书写。

如果自定义了有参构造,那么虚拟机将不再提供默认的无参构造,在创建对象时将不能再使用无参构造。如果还需要使用无参构造,则需要我们自己手动书写无参构造。因此,建议如果写了自定义的有参构造,那么不管是否会用到无参构造,都再手动书写一个无参构造。

综上,要么自己一个构造函数也不要写,要么空参和带参的构造函数都自己手动书写。

带参构造和无参构造是构造方法的重载。

程序示例:

JavaBean 类:

public class Student {
    private int age;
    private String name;

    // 空参构造,虚拟机自动添加的构造方法就和这个长得一样
    public Student() {
    }

    // 带参构造
    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试类:

public class StudentTest {
    public static void main(String[] args) {
        Student student1 = new Student();
        System.out.println(student1.getAge());        // 0
        System.out.println(student1.getName());       // null
        Student g2 = new Student(23, "小张");
        System.out.println(g2.getAge());        // 23
        System.out.println(g2.getName());       // 小张
        // 进行修改
        g2.setAge(25);
        g2.setName("小王");
        System.out.println(g2.getAge());        // 25
        System.out.println(g2.getName());       // 小王
    }
}
posted @ 2026-03-15 17:42  YouKong  阅读(0)  评论(0)    收藏  举报