当前位置: 首页 > article >正文

java —— 面向对象(上)

一、类的封装

在 Java 中,封装是面向对象编程的三大基本特性之一(另外两个是继承和多态),封装是一种将对象的内部状态和实现细节隐藏起来,通过公共方法提供对这些状态的访问和修改的编程机制。它有助于提高代码的安全性、可维护性和模块化,是面向对象编程中非常重要的一个概念。

// 定义好一个类,实现封装
class Student {
    // 定义两个私有属性
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }

    public void setName(String stuName) {
        name = stuName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int stuAge) {
        //
        if (stuAge <= 0) {
            System.out.println("年龄不合法");
        } else {
            age = stuAge;
        }
    }

    public void introduce() {
        System.out.println("姓名:" + name + "\t" + "年龄:" + age);
    }
}

// 调用上面封装好的代码
class Ex04 {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setAge(-30);
        stu.setName("小白");
        stu.introduce();
        
        stu.setName("大白");
        stu.setAge(22);
        stu.introduce();
    }
}

(一)代码解释:

  1. Student 类

    • 属性

      • private String name;:定义一个私有的字符串属性 name,用于存储学生的姓名。
      • private int age;:定义一个私有的整数属性 age,用于存储学生的年龄。
    • 访问器和修改器方法(Getter 和 Setter)

      • public String getName() 和 public void setName(String stuName)

        • getName() 方法用于获取 name 属性的值。
        • setName(String stuName) 方法用于设置 name 属性的值,将 stuName 赋值给 name
      • public int getAge() 和 public void setAge(int stuAge)

        • getAge() 方法用于获取 age 属性的值。
        • setAge(int stuAge) 方法用于设置 age 属性的值,但在设置之前会检查 stuAge 的值。
        • if (stuAge <= 0) {...}:如果 stuAge 小于或等于 0,会输出 "年龄不合法",不修改 age 属性;否则将 stuAge 赋值给 age
    • introduce 方法

      • public void introduce()
        • 输出学生的姓名和年龄,使用 System.out.println("姓名:" + name + "\t" + "年龄:" + age); 进行输出。
  2. Ex04 类的 main 方法

    • 创建对象

      • Student stu = new Student();:创建一个 Student 类的新对象 stu
    • 设置和获取属性

      • stu.setAge(-30);

        • 调用 setAge 方法,尝试将年龄设置为 -30,由于 -30 不合法,会输出 "年龄不合法"。
      • stu.setName("小白");

        • 调用 setName 方法,将姓名设置为 "小白"。
      • stu.introduce();

        • 调用 introduce 方法,输出学生的信息,此时年龄不会被修改,仍为默认值(这里默认为 0,因为 int 类型的默认值是 0),输出类似于 "姓名:小白 年龄:0"。
      • stu.setName("大白");

        • 再次调用 setName 方法,将姓名修改为 "大白"。
      • stu.setAge(22);

        • 调用 setAge 方法,将年龄设置为 22,这是一个合法的年龄。
      • stu.introduce();

        • 再次调用 introduce 方法,输出学生的信息,此时输出 "姓名:大白 年龄:22"。

二、构造方法 and 构造方法的重载

(一)构造方法

class Person {
    int age;

    // 定义有参数的构造方法
    public Person(int a) {
        age = a;
    }

    public void speak() {
        System.out.println("I am " + age + " years old!");
    }

}

public class Ex06_03 {
    public static void main(String[] args) {
        Person p = new Person(20);
        p.speak();
    }
}

(二)构造方法的重载

class Person1 {
    String name;
    int age;

    // 定义两个参数的构造方法
    public Person1(String con_name, int con_age) {
        name = con_name;
        age = con_age;
    }

    // 定义一个参数的构造方法
    public Person1(String con_name) {
        name = con_name;
    }

    public void speak() {
        System.out.println("大家好,我叫" + name + age);
    }
}

public class Ex07_03{
    public static void main(String[] args) {
        Person1 p1 = new Person1("c的");
        Person1 p2 = new Person1("aa",22);
        p1.speak();
        p2.speak();
    }
}

代码解释:

  1. Person1 类

    • 成员变量

      • String name;:定义一个字符串类型的成员变量,用于存储人的名字。
      • int age;:定义一个整数类型的成员变量,用于存储人的年龄。
    • 构造方法

      • 两个参数的构造方法

        • public Person1(String con_name, int con_age) {...}
          • 当使用 new Person1("aa", 22); 创建对象时,会调用此构造方法。
          • 接收 con_name 和 con_age 作为参数,将 con_name 赋值给 name 成员变量,将 con_age 赋值给 age 成员变量。
      • 一个参数的构造方法

        • public Person1(String con_name) {...}
          • 当使用 new Person1("c的"); 创建对象时,会调用此构造方法。
          • 仅接收 con_name 作为参数,将 con_name 赋值给 name 成员变量,而 age 成员变量未被初始化,会采用其数据类型的默认值(int 的默认值为 0)。
    • speak 方法

      • public void speak() {...}
        • 此方法用于输出该 Person1 对象的信息。
        • System.out.println("大家好,我叫" + name + age);:将 name 和 age 拼接成一个字符串并输出。
  2. Ex07_03 类

    • main 方法
      • public static void main(String[] args):程序的入口点。

      • 创建对象

        • Person1 p1 = new Person1("c的");

          • 创建一个 Person1 对象 p1,使用一个参数的构造方法,仅传递 name 为 "c的"age 为默认值 0。
        • Person1 p2 = new Person1("aa", 22);

          • 创建一个 Person1 对象 p2,使用两个参数的构造方法,传递 name 为 "aa"age 为 22。
      • 调用方法

        • p1.speak();

          • 调用 p1 对象的 speak 方法,输出信息,由于 p1 的 age 未初始化,输出为 "大家好,我叫c的0"
        • p2.speak();

          • 调用 p2 对象的 speak 方法,输出信息,输出为 "大家好,我叫aa22"

三、this()关键字

(一)案例一

1. 指代当前对象

  • this 关键字用于指代当前正在操作的对象。在一个类的实例方法中,它可以用来访问该类的实例变量和实例方法,以区分局部变量和实例变量。

2. 解决命名冲突

  • 当方法的参数或局部变量与实例变量同名时,使用 this 可以明确表示正在操作的是实例变量

下面的代码执行的是有参数的Person2,因为有this(),所有执行了实例变量的无参数

class Person2{
    public Person2(){
        System.out.println("无参数");
    }

    public  Person2(String name){
        this();
        System.out.println("有参数");
    }
}


public class Ex10_03 {
    public static void main(String[] args) {
        Person2 p = new Person2("biaobai");
    }
}

没有this()关键字

class Person2{
    public Person2(){
        System.out.println("无参数");
    }

    public  Person2(String name){
//        this();
        System.out.println("有参数");
    }
}


public class Ex10_03 {
    public static void main(String[] args) {
        Person2 p = new Person2("biaobai");
    }
}

(二)案例二

class Person3 {
    private String name;

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

    public String getName() {
        return this.name;
    }

    public void introduce() {
        System.out.println("My name is " + this.getName());
    }
}
class eww{
    public static void main(String[] args) {
        Person3 p3 = new Person3();
        p3.setName("是我");
        p3.introduce();
    }
}

代码解释:

  1. Person3 类

    • 属性

      • private String name;
        • 这是一个私有属性,用于存储 Person3 对象的名字。因为是私有属性,只能在 Person3 类内部访问,外部类无法直接访问。
    • 方法

      • public void setName(String name)

        • 这是一个公共方法,用于设置 Person3 对象的名字。
        • this.name = name;:使用 this 关键字,this.name 表示对象的 name 属性,将传入的参数 name 的值赋给对象的 name 属性。
      • public String getName()

        • 这是一个公共方法,用于获取 Person3 对象的名字。
        • return this.name;:返回对象的 name 属性的值。
      • public void introduce()

        • 这是一个公共方法,用于让 Person3 对象进行自我介绍。
        • System.out.println("My name is " + this.getName());:调用 getName() 方法获取对象的名字,并将其输出。
  2. eww 类的 main 方法

    • 创建对象

      • Person3 p3 = new Person3();:创建一个 Person3 类的新对象 p3
    • 调用方法

      • p3.setName("是我");

        • 调用 p3 对象的 setName 方法,将名字设置为 "是我"
      • p3.introduce();

        • 调用 p3 对象的 introduce 方法,让 p3 对象进行自我介绍,输出 "My name is 是我"

四、static()关键字

(一)静态变量

class Student1 {
    // 定义成员变量为静态,也就是只有一个赋值,不会发生重新赋值
    static String schoolName;

}

public class Ex12_03 {
    public static void main(String[] args) {
        Student1 stu1 = new Student1();
        Student1 stu2 = new Student1();
        Student1.schoolName = "我的小白";
        System.out.println("我的名字是1:" + Student1.schoolName);
        System.out.println("我的名字是2:" + Student1.schoolName);
    }
}

(二)静态方法

class Person4{

    // 静态方法
    public static void sayHello(){
        System.out.println("hello");
    }
    
    // 非静态方法
    public void sayHello2(){
        System.out.println("hello2");
    }
}


public class Ex13_03 {
    public static void main(String[] args) {
        // 可以直接调用,不需要创建对象
        Person4.sayHello();

        Person4 p4 = new Person4();
        p4.sayHello2();
    }
}

(三)静态代码块

1、静态代码块使用 static 关键字和花括号 {} 来定义,并且它会在类加载时执行,只执行一次。例如:

class MyClass {
    static {
        // 静态代码块中的代码
        System.out.println("这是一个静态代码块");
    }
}

 2、可以看到没有main函数,依然可以输出

class Ex14_03 {
    // 静态代码块
    static {
        System.out.println("测试类的静态代码块执行了");
    }

3、不加载类不会执行static

class Ex14_03 {
    // 静态代码块
    static {
        System.out.println("测试类的静态代码块执行了");
    }

    public static void main(String[] args) {
        // 下面的代码创建两个Person对象
//        Person5 p1 = new Person5();
//        Person5 p2 = new Person5();

    }
}

class Person5{
    static String country;
    // 静态代码块
    static {
        country = "小白";
        System.out.println("Person5的静态代码块"+country);
    }

}

 

4、加载类,static执行

class Ex14_03 {
    // 静态代码块
    static {
        System.out.println("测试类的静态代码块执行了");
    }

    public static void main(String[] args) {
        // 下面的代码创建两个Person对象
        Person5 p1 = new Person5();
        Person5 p2 = new Person5();

    }
}

class Person5{
    static String country;
    // 静态代码块
    static {
        country = "小白";
        System.out.println("Person5的静态代码块"+country);
    }

}

五、内部类

(一)成员内外部类

1、外部类

class Outer {
    private int num = 4;

    // 定义了一个成员方法,方法中访问内部类
    public void test() {
        Inner inner = new Inner();
        inner.show();
    }

    // 定义了一个成员内部类
    class Inner {
        void show() {
            // 在成员内部类分方法中访问外部类的成员变量
            System.out.println("num=" + num);
        }
    }

}

public class Ex16_03 {
    public static void main(String[] args) {
        Outer outer = new Outer();  // 创建外部类对象
        outer.test();
    }
}

2、内部类

成员内部类是定义在外部类内部的类,作为外部类的一个成员存在,因此它可以使用外部类的所有成员(包括私有成员)。

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

public class Ex17_03 {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.show();
    }
}

(二)静态内部类

class Outer1 {
    private static int num = 6;

    
    // 静态内部类
    static class Inner {
        void show() {
            System.out.println("num=" + num);
        }
    }
}


public class Ex18_03 {
    public static void main(String[] args) {
        Outer1.Inner inner = new Outer1.Inner();
        inner.show();
    }
}

(三)方法内部类

class Outer2 {
    private int num = 4;

    public void test() {
        // 在方法中定义内部类
        class Inner {
            void show() {
                System.out.println("num=" + num);
            }
        }
        Inner in = new Inner();
        in.show();      // 这里调用show()方法,所以下面直接outer2.test();就可以拿到返回值
    }
}

public class Ex19_03 {
    public static void main(String[] args) {
        Outer2 outer2 = new Outer2();
        outer2.test();
    }
}


http://www.kler.cn/a/517656.html

相关文章:

  • Spring整合Mybatis、junit纯注解
  • Stable Diffusion 3.5 介绍
  • 全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析
  • 导出地图为图像文件
  • 使用python调用JIRA6 进行OAuth1认证获取AccessToken
  • Mac 上管理本地 Go 版本
  • [Dialog屏幕开发] 屏幕绘制(Table Control控件)
  • 为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️
  • K8S中ingress详解
  • 数据结构测试题1
  • DeepSeek-R1:将强化学习用于激励大型语言模型的推理能力
  • 设计模式:春招面试的关键知识储备
  • ubunut22.04安装docker(基于阿里云 Docker 镜像源安装 Docker)
  • mapbox加载geojson,鼠标移入改变颜色,设置样式以及vue中的使用
  • web前端8--浮动
  • Python面向对象编程:精雕细琢对象的“名片”——重写 `__str__()` 和 `__repr__()` 方法
  • 【函数题】6-1 单链表逆转
  • 三高“高性能、高并发、高可靠”系统架构设计系列文章
  • 计算机视觉之三维重建-单视几何
  • jenkins-通过api获取所有job及最新build信息
  • hedfs和hive数据迁移后校验脚本
  • Rust 中的引用与借用:深入理解所有权与数据安全
  • 多模态数据融合的基本流程与关键环节
  • elementPlus-button组件二次封装
  • LlamaV-o1:重塑大型语言模型中的逐步视觉推理
  • 最长递增——蓝桥杯