Java 3——getter和setter super()关键字

getter和setter

在面向对象编程中,我们通常将类的成员变量(属性)声明为 private,以隐藏内部实现细节,防止外部直接访问和修改。但有时外部需要读取或修改这些属性的值,此时就需要提供公开的 getter(获取)和 setter(设置)方法。

核心目的:实现封装 ------ 将数据和行为包装在类内部,对外提供受控的访问接口。

成员变量一般使用private来声明,保护成员变量不被胡乱赋值

好处:

1.控制读写权限(只读:只有 getter,没有 setter)

2.校验数据合法性(在 setter 中检查边界)

3.统一修改接口(便于日后扩展,如增加日志、触发事件)

4.隐藏内部表示(可以改变内部存储方式而不影响外部代码)

setter:主要是给成员变量赋值,做一定的保护

getter:从成员变量中获取数据

命名规范:

|------------------------|------------------------------|-------------------------------|
| 类型 | 方法命名格式 | 示例(属性 name) |
| getter | public 返回值类型 getXxx() | public String getName() |
| setter | public void setXxx(参数类型 参数名) | public void setName(String n) |
| boolean 类型的 getter(可选) | public boolean isXxx() | public boolean isMarried() |

快捷键:

空白位置->右键->generate->getter and setter->全选->OK

java 复制代码
public class Student {
    private String name;   // 私有属性
    private int age;
    private boolean married;

    // getter
    public String getName() {
        return name;
    }
    
    // setter
    public void setName(String name) {
        this.name = name;   // this 区分成员变量和参数
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {   // 数据校验
            this.age = age;
        } else {
            System.out.println("年龄不合法!");
        }
    }
    
    // boolean 类型推荐使用 isXxx
    public boolean isMarried() {
        return married;
    }
    
    public void setMarried(boolean married) {
        this.married = married;
    }
}

使用示例:

java 复制代码
Student s = new Student();
s.setName("张三");
s.setAge(20);
System.out.println(s.getName() + " 年龄:" + s.getAge());
与封装的关系图解

┌─────────────────────────────────┐

│ Student │

├─────────────────────────────────┤

│ - name : String │ ← private 属性(隐藏)

│ - age : int │

├─────────────────────────────────┤

│ + getName() : String │ ← public getter

│ + setName(String) : void │ ← public setter(带校验)

│ + getAge() : int │

│ + setAge(int) : void │

└─────────────────────────────────┘

│ 通过公开方法访问

外部代码(Client)

继承

继承:子类可以自动拥有父类除了私有内容外的其他所有内容

当出现x是一种y的时候,x就可以继承y

写法:public class 类 extends 父类 {}

Java 不支持多继承,一个子类只能有一个直接父类

作用:

简化代码的开发

子类对父类进行了扩展

java 复制代码
// 父类
public class Animal {
    String name;
    int age;
    
    public void eat() {
        System.out.println(name + "正在吃东西");
    }
}

// 子类 Dog 继承 Animal
public class Dog extends Animal {
    // 自动拥有了 name、age 属性和 eat() 方法
    public void bark() {
        System.out.println(name + "汪汪叫");
    }
}

// 使用
Dog dog = new Dog();
dog.name = "旺财";
dog.age = 2;
dog.eat();   // 旺财正在吃东西
dog.bark();  // 旺财汪汪叫
继承中的成员访问规则

|---------|-----------------------------------------------|
| 访问 | 子类中能否直接访问(不通过父类引用) |
| public | ✅ 可以 |
| default | 仅当子类与父类在同一个包时才可以 |
| private | ❌ 不可以(但可以通过父类提供的 public/protected 方法间接访问) |

子类只继承父类中非 private 的成员变量和方法。构造方法不能被继承,但可以在子类中调用。

super()关键字

super:表示父类中的内容;this:表示自己类中的内容(用super和this来区分父类和子类中重名的内容)

java 复制代码
public class Hero {
    String name = "英雄";
}


public class SunWuKong extends Hero{
    String name = "孙大圣";
    public void chi() {
        //先找自己类,再找父类
        System.out.println(this.name + "在吃桃子");
        //如果此时想看到父类中的内容
        System.out.println(super.name + "在吃桃子");
    }
    public static void main(String[] args) {
        SunWuKong s = new SunWuKong();
        s.chi();
    }
}
java 复制代码
public class Hero {
    String name = "英雄";
    public Hero() {
        System.out.println("我是父类的构造方法");
    }
}


public class SunWuKong extends Hero{
    String name = "孙大圣";
    public SunWuKong() {
        //程序是先执行这个子类构造,但是在这个位置会隐含着super(); 所以最后会先输出父类的构造
        //还原程序:在子类构造方法的第一行,默认调用父类的构造方法
        System.out.println("我是子类的构造方法");
    }
    public void chi() {
        System.out.println(this.name + "在吃桃子");
        System.out.println(super.name + "在吃桃子");
    }
    public static void main(String[] args) {
        SunWuKong s = new SunWuKong();
        s.chi();
    }
}

/*输出:
我是父类的构造方法
我是子类的构造方法
孙大圣在吃桃子
英雄在吃桃子*/

创建对象的过程:先创建父类的对象,然后创建子类的对象

super 是 Java 中用于引用父类对象的关键字。它主要用于三个方面:

调用父类的构造方法(super() 或 super(参数))(必须写在子类构造方法的第一行,如果父类的构造是无参数的,可以不写,如果父类没有无参数的构造,必须要写super)

访问父类的成员变量(super.变量名)

调用父类的成员方法(super.方法名())

调用父类的构造方法

子类构造方法必须调用父类的构造方法(隐式或显式)。如果父类没有无参构造,子类必须在第一行显式调用 super(参数)。

java 复制代码
super();           // 调用父类无参构造
super(参数列表);    // 调用父类有参构造

规则

1.super() 必须写在子类构造方法的第一行

2.super()this() 不能同时出现(都要求在第一行)

3.如果子类构造方法没有写任何 super(),编译器会自动添加 super()

java 复制代码
class Person {
    String name;
    Person(String name) {
        this.name = name;
    }
}

class Student extends Person {
    int score;
    Student(String name, int score) {
        super(name);   // 必须显式调用父类有参构造
        this.score = score;
    }
}
访问父类的成员变量

当子类定义了与父类同名的变量时,使用 super 可以区分并访问父类的变量

java 复制代码
class Father {
    String name = "父亲";
}

class Son extends Father {
    String name = "儿子";
    void print() {
        System.out.println(name);       // 儿子
        System.out.println(super.name); // 父亲
    }
}
调用父类的成员方法

当子类重写了父类的方法,使用 super 可以调用父类中被覆盖的版本

java 复制代码
class Animal {
    void sound() {
        System.out.println("动物发出声音");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        super.sound();   // 调用父类的 sound()
        System.out.println("喵喵喵");
    }
}
superthis 的区别

|-------|------|----------------------|
| 关键字 | 指向 | 用途 |
| this | 当前对象 | 访问当前对象的成员、调用本类其他构造方法 |
| super | 父类对象 | 访问父类的成员、调用父类构造方法 |

注意

在静态方法中不能使用 thissuper(因为不存在当前对象/父类对象)

super 并不是一个引用变量(不能赋值),它只是一个指示编译器调用父类成员的关键字

常见误区与注意事项

1.父类没有无参构造时,子类必须显式调用有参构造

java 复制代码
class Parent {
    Parent(int x) {}
}
class Child extends Parent {
    Child() {
        super(10);   // 必须
    }
}

2.super()和 this()不能构造

因为两者都要求位于构造方法的第一行,只能选择其一。

3.不能通过 super 访问父类的 private 成员
private 成员在子类中不可见,即使是 super 也无法访问。

4.super 调用方法时,仍然遵循动态绑定

若父类方法被子类重写,super.方法() 调用的是父类版本,而不是子类版本。

相关推荐
wand codemonkey1 小时前
(二十七)Maven(依赖)【安装】+【项目结构】
java·开发语言·maven
linda公馆1 小时前
Maven项目报错:java:错误:不支持发行版本 5
java·开发语言·maven
Ulyanov1 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 可视化革命——基于 PyVista 的 3D 战场构建与实时渲染
开发语言·python·算法·3d·系统仿真
Heaphaestus,RC1 小时前
Slate到UMG的封装原理揭秘
开发语言·ue5
学习中.........1 小时前
常见设计模式
java·设计模式
爱喝热水的呀哈喽1 小时前
一段即插即用的hypermesh命令行
开发语言·python
Ulyanov1 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 终极试炼——全链路综合仿真与蒙特卡洛打靶
开发语言·python·系统仿真·雷达电子对抗
敖正炀1 小时前
JDBC 到 ORM:Spring Data JDBC、JPA 与 MyBatis 的定位与选型
java
@大迁世界1 小时前
45.什么是内联条件表达式(inline conditional expressions)?在事件处理里怎么用?
开发语言·前端·javascript·react.js·ecmascript