8、面向对象:类、封装、构造方法

一、类

1、定义

类:对现实世界中事物的抽象。Student

对象:现实世界中具体的个体。张三、李四 这些具体的学生

面向对象的特征:抽象、封装、继承、多态

OOP: Object Oriented Programming(面向对象编程)

类和对象的总结:

1、现实世界都是由很多对象组成的,基于对象的共同特征抽象出类。

2、对象:真实存在的对象

3、类中包含:

 1)所有对象所共有的特征--属性(静)
 
 2)所有对象所共有的行为--方法(动)

4、类是对象的模板,对象是类的具体实例。

5、一个类可以创建多个对象, 同一个类的不同对象,结构相同,数据不同。

java 复制代码
//实体类:和数据库表一一对应
public class Student {
    //属性、字段
    int id;
    String name;
    int age;
    String gender;
}

@Test
public void test1() {
    Scanner scanner = new Scanner(System.in);
    int num = 3;
    //student1:变量、实例、对象
    Student student1 = new Student();
    //对象.属性
    student1.id = 1;
    student1.name = "张三";
    student1.age = 23;
    student1.gender = "男";
    System.out.println(student1.name);

    Student student2 = new Student();
    student2.id = 2;
    student2.name = "李四";
    student2.age = 24;
    student2.gender = "女";
    System.out.println(student2.name);
    
    //构造数组来存储,方便管理:
    Student[] array = new Student[2];
    array[0] = student1;
    array[1] = student2;
    }
}

对应的内存模型:

new出来的放在堆里面,类的模板放在方法区

2、易混淆知识点

bash 复制代码
int num = 3;
int[] nums = new int[3];
double[] nums = new double[3];
Student student = new Student();  // student :变量、实例、对象
Student[] students = new Student[3];
Teacher teacher = new Teacher();
Teacher[] teachers = new Teacher[3];

int、int[]、Student、Student[]这些都是数据类型,数据类型的后面是这种类型的一个变量。
格式: 数据类型  变量
var v;
let v;

1.Java是编译型、强类型语言(效率高)
2.JavaScript是解释型、弱类型语言

3、数据类型的默认值

bash 复制代码
1.int类型默认值是:0
2.double类型默认值是:0.0
3.boolean类型默认值是:false
4.String类型默认值是:null
5.int[]类型默认值是:null
6.Student[]类型默认值是:null
7.boolean[]类型默认值是:null

所有引用数据类型的默认值都是null
bash 复制代码
1.int[] array = new int[3]; 里面的存放默认值是0
2.boolean[] array = new boolean[3]; 里面的存放默认值是false
3.Student[] array = new Student[3];里面的存放默认值是null(Student是一个类,放的就是类的默认值:null)

总结:构造一个数组的时候如果没有赋值,那么数组里面放的是这个类型的默认值
java 复制代码
@Test
public void test2() {
    Student student = new Student();
    System.out.println(student.id);//0
    System.out.println(student.name);//null
}

@Test
public void test3() {
    int[] array1 = new int[3];
    boolean[] array2 = new boolean[3];
    Student[] students = new Student[3];
    for (int i = 0; i < students.length; i++) {
        System.out.println(students[i]);
    }
    //增强的for循环
    for (Student student : students) {
        System.out.println(student);
    }
}

4、空指针异常

bash 复制代码
ArrayIndexOutOfBoudsException 数组下标越界异常

NullPointerException空指针异常(引用数据类型)
java 复制代码
@Test
public void test4() {
    //NullPointerException空指针异常(引用数据类型)
    Student student = null;
    System.out.println(student);//null
    // null.方法   null.属性 --->空指针异常
    System.out.println(student.id);//空指针异常
}

二、toString()

1、行为--->方法:

基于上面学生的例子演示方法的调用:

上述例子是写死的,我们实际应当实现灵活调用:即以前说的,先写死,再改成逗逗加加:

那么,如果属性很多,进行拼接会很麻烦,解决办法:添加toString()方法生成这些,如下。

2、添加toString():

java 复制代码
//方法:自己手敲的
public String getInfo() {
    //String str = "[Student: id="+id+",name="+name+",age="+age+",gender="+gender+"]";
    //return str;
    return "[Student: id="+id+",name="+name+",age="+age+",gender="+gender+"]";
}

//toString()生成的:
@Override
public String toString() {
    return "Student{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            ", gender='" + gender + '\'' +
            '}';
}
java 复制代码
@Test
public void test44() {
    Student student = new Student();
    student.id = 1;
    student.name = "王五";
    student.age = 223;
    student.gender = "男";
    String info = student.getInfo();
    System.out.println(info);
    System.out.println(student.getInfo());
    System.out.println("-----------");
    System.out.println(student.toString());
    //当打印对象的时候,默认就调用了:对象.toString()
    System.out.println(student);
}

完整代码:

java 复制代码
package com.situ.day10;

public class Student {
    int id;
    String name;
    int age;
    String gender;

    //自己写的方法
    public String getInfo(){
        String str = "[student:id = "+id+",name = "+name+",age = "+age+"]";
        return str;
    }

    //toString()生成的:
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
java 复制代码
package com.situ.day10;

import org.junit.Test;

public class OPPDemo {
    @Test
    public void test1(){
        Student student1 = new Student();
        student1.id = 1;
        student1.name = "zhangsan";
        student1.age = 23;
        student1.gender = "男";
        //调用toString()并输出结果
        System.out.println(student1.toString());

        Student student2 = new Student();
        student2.id = 2;
        student2.name = "lisi";
        student2.age = 24;
        student2.gender = "女";
        //System.out.println(student2.toString());等价于下面这行代码:
        System.out.println(student2);//即打印对象的时候,默认调用toString()。

    }
}

补充:

三、封装 private/get/set

面向对象的封装是一种编程概念和原则,它通过将数据和操作封装在一个对象中,以实现信息隐藏和安全性。

封装使得对象的内部细节对外部不可见,只暴露必要的接口供其他对象进行交互。

java 复制代码
//属性私有private,只有类的内部可以访问
private age;

// 属性私有,通过get、set方法访问:
public void setAge(int age) {
    if (age >= 1 && age <= 125) {
        // The assignment to variable age has no effect
        // this.age 代表的就是属性age
        this.age = age;
    }
}

public int getAge() {
    // return age;
    return this.age;
}

完整代码:

java 复制代码
package com.situ.day10;

public class Student2 {
    //封装:变量私有化处理:
    // 添加private,只能在当前类中使用,通过get、set方法访问:
    private int id;
    private String name;
    private int age;
    private String gender;


    //右键Generate:添加Getter、Setter方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 1 && age <= 125) {//根据实际情况添加限制
            this.age = age;
        }
    }
    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    //添加toString方法:

    @Override
    public String toString() {
        return "Student2{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
java 复制代码
package com.situ.day10;

import org.junit.Test;

public class OOPDemo2 {
    @Test
    public void test1(){
        Student2 student4 =new Student2();
        student4.setAge(15);
        int age = student4.getAge();
        System.out.println(age);
    }

    @Test
    public void test2(){
        Student2 student5 = new Student2();
        student5.setId(5);
        student5.setName("wangwu");
        student5.setAge(15);
        student5.setGender("女");
        System.out.println(student5);
    }

}

四、构造方法

bash 复制代码
构造方法是new对象时候调用方法,特点:

1.方法名和类名一样  

2.没有返回值

3.在new对象的时候会调用构造方法
java 复制代码
//无参构造方法
//如果不写,Java默认提供这样一个无参构造方法.
//如果你写了任何一个构造方法,Java就不会再提供这个无参构造方法
public Student() {
   System.out.println("Student.Student()");
}

//有参构造方法
public Student(int id, String name, int age, String gender) {
   this.id = id;//把1这个值赋值给当前new出来的student对象的id属性
   this.name = name;
   this.age = age;
   this.gender = gender;
}

Student student = new Student(2, "李四", 24, "男");
System.out.println(student);
bash 复制代码
1、如果不写任何构造方法,系统默认提供一个无参数构造方法,只是我们看不到而已。
2、如果自己写了任何一个构造方法,不管有参没参,系统就不会提供这个默认无参构造方法。
3、自己写了一个带参数的构造方法,就要把无参数构造方法也要写上。
(后面使用或者学习的一些框架要new这个无参数的构造方法)
bash 复制代码
构造方法和一般方法的不同:
1、构造方法是在new对象的时候运行,而一般的方法是在对象调用的时候才执行。
2、一个对象的建立,构造方法只执行一次,而一般方法可以被改对象调用多次。

五、作业

1、编写Java程序,模拟简单的计算器。

定义名为Cal的类,其中有两个整型数据成员num1和num2,应声明为私有。编写构造方法,赋予num1和num2初始值,再为该类定义加(add)、减(sub)、乘(multi)、除(div)等公有成员方法,分别对两个成员变量执行加、减、乘、除的运算。

在main方法中创建Cal类的对象,调用各个方法,并显示计算结果。

java 复制代码
package com.situ.day11;

public class Cal {
    private int num1;
    private int num2;

    //无参构方法:
    public Cal(){

    }

    //有参构造方法:
    public Cal(int num1,int num2){
        this.num1 = num1;
        this.num2 = num2;
    }

    public int add(){
        int result = num1 + num2;
        return result;
        //return num1 + num2;
    }

    public int sub(){
        int result= num1 - num2;
        return result;
    }

    public int multi(){
        int result = num1 * num2;
        return result;
    }

    public int div(){
        int result = num1 / num2;
        return result;
    }

    public static void main(String[] args) {
        //创建对象:
        Cal cal = new Cal(5,10);
        System.out.println(cal.add());
        System.out.println(cal.sub());
        System.out.println(cal.multi());
        System.out.println(cal.div());
    }
}

2、定义长方形类,含:

属性:宽、高(整型);

构造方法3个:(1)无参------宽、高默认值为1;(2)1个参数------宽、高相等;(3)2个参数------宽、高各为参数值。

方法:求周长、面积;

要求:进行测试计算周长和面积。

java 复制代码
package com.situ.day11;

import org.junit.Test;

public class Rect {
    private int width;
    private int height;
    //无参构造方法:
    public Rect(){

    }

    //有参构造方法
    public Rect(int width, int height) {
        this.width = width;
        this.height = height;
    }

    //一个参数的构造方法
    public Rect(int width){
        this.width = width;
        this.height = width;
    }

    //方法:
    public int zhouChang(){
        return (width + height) * 2;
    }
    public int mianJi(){
        return width * height;
    }

    //测试:
    public static void main(String[] args) {
        Rect rect = new Rect(3,5);
        System.out.println(rect.zhouChang());
        System.out.println(rect.mianJi());
    }

}
相关推荐
fly spider1 小时前
JVM- 垃圾回收算法
java·jvm·算法·gc
苹果醋31 小时前
机器学习算法在网络安全中的实践
java·运维·spring boot·mysql·nginx
_Eden_1 小时前
Docker技术相关学习三
java·学习·docker
Future_yzx1 小时前
Docker使用指南(一)——镜像相关操作详解(实战案例教学,适合小白跟学)
java·spring cloud·eureka
pps-key2 小时前
JAVA Web 开发
java
计算机-秋大田2 小时前
基于SpringBoot的农村电子商务系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
java·spring boot·后端
大耳朵土土垚2 小时前
【Linux】线程池封装与介绍
java·linux·运维
2的n次方_3 小时前
Nacos 的介绍和使用
java·spring boot·spring cloud·微服务·云原生·nacos
武昌库里写JAVA3 小时前
机器学习,深度学习,神经网络,深度神经网络
java·开发语言·spring boot·学习·课程设计
buame3 小时前
Ajax:重塑Web交互体验的人性化探索
java·ajax·eclipse