# 面向对象的概念

# 什么是类

类是 Java 程序最小的组成单位,计算机是用以模拟现实世界的,所以我们需要使用 Java 类去描述世界上的任何一种食物,类是对现实生活中一类具有共同属性和行为的事物的抽象。类是对事物,也就是对象的一种描述,可以将类理解为一张设计图,根据设计图,可以创建出具体存在的事物。

# 类与对象的关系

类是一类事物的抽象
1646047942816.png
对象
1646048001584.png
类:类是对现实生活中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸得着的真实存在的实体
1646048068152.png

# 如何定义类

定义类的格式

public class 类名 {
    // 成员变量
    变量1的数据类型 变量1;
    变量2的数据类型 变量2;// 成员方法
    方法1;
    方法2;
}

示例 1 代码:
需求:使用 Java 类描述一个学生类,学生具有的属性:name、age,一个学习的行为

package _01类的定义;

public class Student {

    //描述
    String name;

    //描述年龄
    int age;

    public void study(){
        System.out.println("good good study ,day day up");
    }

}

创建对象

public class Demo1 {

    public static void main(String[] args) {
        //创建Studend对象
        Student s = new Student();
        //给对象的属性复制
        s.name="狗娃";
        s.age=12;
        //访问对象的属性
        System.out.println("姓名:"+s.name);
        System.out.println("年龄:"+s.age);
        s.study();

    }
}

示例 2 代码

public class Phone {

    //一类事务的公共属性使用成员变量去描述
    //品牌属性
    String brand;

    //价格属性
    double price;


    //一类事务的公共行为使用成员方法描述(注意:这里的方法不能使用static去修饰,为什么?就业班第一天讲解)
    public void call(){
        System.out.println("打电话....");  //方法内部是可以直接访问成员变量的值
    }

    //发短信
    public void sendMessage(){
        System.out.println("发短信..");
    }

}

创建对象

/*
类的概念: 同一类事务公共的属性与行为的抽象。

对象:具体的某一个事物。

定义类的格式:
    public class 类名{

        该类事物的公共属性使用成员变量去描述

        该类事务的公共行为使用成员方法去描述。

    }

通过类创建对象的格式:
    类名  变量名 = new  类名();

访问对象的属性:
    变量名.属性名
给对象赋予属性值:
    变量名.属性名= 属性值;

调用对象的方法:
    变量名.方法名();


 */

public class PhoneDemo {

    public static void main(String[] args) {
        //1. 创建一个手机对象
        Phone  p = new Phone();
        //给对象的属性赋值
        p.brand = "肾13";
        p.price = 13000;
        //访问对象的属性
        System.out.println("品牌:"+ p.brand+" 价格:"+ p.price);

        //调用对象的方法
        p.call();

    }
}

# 练习

需求:为在线影院系统”定义一个“电影(Movie)类,有以下成员:

  • 成员属性:影片名称(movieName)、导演(director)、编剧(script)、主演(starring)
  • 成员方法:打印电影信息(print)

定义测试类 Demo03Movie,创建两个 Movie 对象,并存储两部电影信息:

public class Movie {

    //影片名称
    String movieName;

    //导演
    String director;

    //编剧
    String script;

    //主演
    String starring;


    public void print(){
        System.out.println("影片名称:"+movieName);
        System.out.println("导演:"+movieName);
        System.out.println("影片名称:"+movieName);
        System.out.println("影片名称:"+movieName);
    }
}

MovieDemo

public class MovieDemo {

    public static void main(String[] args) {
        Movie movie = new Movie();
        movie.movieName="水门桥";
        movie.starring="吴京";
        movie.director="吴京";
        movie.script="吴京";

        movie.print();
    }
}

# 内存分析

详细请看 ppt 动画

# 成员变量与局部变量的区别

1646051006193.png

# this 关键字

# 局部变量与成员变量同名情况

public class Student {

    //成员变量
    int age = 18;

    public void getAge(){
        //局部变量
        int age = 19;
        //如果成员变量与局部变量存在同名的情况,默认访问的是局部变量
        System.out.println("年龄:"+age);
    }

}
/*
现象:
    在方法中成员变量与局部变量一旦存在同名的情况下,
    java默认采取"就近原则"机制去访问,会访问局部变量。

this关键字: this关键字代表的是当前对象。(哪个对象调用了方法则代表了当前方法调用者对象)

this关键字的作用:成员变量与局部变量存在同名的情况下,默认访问是局部变量,如果你需要访问成员变量那么就在变量的前面添加this关键字即可。


 */

public class EmpDemo {

    public static void main(String[] args) {
        //创建了一个员工对象
        Emp e1 = new Emp();
        //访问方法
        e1.print();
    }
}

# 内部原因分析

没有 this 的情况
1646057874057.png
使用了 this 的情况
1646057954909.png

# this 关键字

this 代表了当前调用者对象,this 解决局部变量与同名变量名同名的情况。

public class Student {

    //成员变量
    int age = 18;

    public void getAge(){
        //局部变量
        int age = 19;
        //如果成员变量与局部变量存在同名的情况,默认访问的是局部变量
        System.out.println("年龄:"+this.age);
    }

}
public class StudentDemo {

    public static void main(String[] args) {
        //1. 创建学生对象
        Student s = new Student();
        s.getAge();
    }
}

# 封装

# 没有封装的弊端

public class Student {

    //描述
    String name;

    //描述年龄
    int age;


    public void study(){
        System.out.println(name+"good good study ,day day up");
    }

}
public class StudentDemo {
    public static void main(String[] args) {
        Student s = new Student();
        s.name="张三丰";
        //直接访问属性,只要是int类型的值都行,但是这个年龄已经远远超出正常人的年龄范围了
        s.age=222222;
    }
}

弊端:外界可以直接访问年龄,可以给年龄赋予任意值,222222 已经超出了正常人的年龄范围了

# private 关键字

  • 是一个权限修饰符
  • 可以修饰成员(成员变量和成员方法)
  • 被 private 修饰的成员只能在本类中才能访问, 被 public 修饰的成员只能在本类中才能访问

# 封装

public class Student {

    //描述
    private String name;

    //描述年龄
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        //年龄在0岁到120岁之间都合法
        if(age>0&&age<120) {
            this.age = age;
        }else{
            System.out.println("您请输入的年龄不合法");
        }
    }

    public void study(){
        System.out.println(name+"good good study ,day day up");
    }

}
public class StudentDemo {

    public static void main(String[] args) {
        Student s = new Student();
        s.setAge(130);
        System.out.println("年龄:"+s.getAge());
    }
}

# 练习

需求:1.定义一个 Cart(员工类),定义成员 Brand(品牌),price(价格),color(颜色),并且提供封装

public class Cart {

    private String brand;

    private double price;

    private String color;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

# 构造方法

# 构造方法存在的意义

public class Student {

    private String name;

    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public static void main(String[] args) {
        Student student = new Student();
        System.out.println("姓名:"+student.getName()+" 年龄:"+student.getAge());
    }
}

存在的问题:创建对象的时候所有的成员都是使用默认值,如果需要实现一旦创建对象就存在指定的属性值没法做到,只能通过 setxx 方法去设置

# 构造方法的概念

构造方法的意义:创建对象的时候初始化对象
构造器注意的事项:

  • 如果我们不定义构造方法,编译器自动添加一个无参、什么都不做的默认构造方法。
  • 如果我们定义了构造方法,编译器就不会再添加默认构造方法。
  • 可以为一个类定义多个构造方法,但“形参列表”不能完全相同,这种形式叫:构造方法重载
  • 构造方法的定义格式
public 类名([形参]) {}
  • 构造方法不能声明返回值类型,内部也不能 return 值,但可以写 return;语句,表示:结束方法的执行
  • 创建一个对象,只能调用一个构造方法

示例:

public class Student {

    private String name;

    private int age;

    //构造方法
    public Student(String name,int age){
        this.name = name;
        this.age=age;
        System.out.println("构造方法被调用了..");
    }

    //构造方法
    public Student(){
        System.out.println("无参的构造方法。。");
    }


    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
/*
构造方法的作用:在创建对象的时候初始化成员变量。

构造方法的格式:

    public 方法名(形参列表){

    }
构造方法要注意的事项:
    1. 构造方法是没有返回值类型的,void也不能写。
    2. 构造方法的方法名必须与类名一致。
    3. 构造方法不能使用对象去调用的,是你创建对象的时候jvm帮你去调用的。
    4. 构造方法是可以以方法重载的形式存在多个的,创建对象具体调用哪个是看创建对象传递的实参。
    5. 一个类如果没有显式的编写一个构造方法,那么默认有一个无参的构造方法,如果一个
    类一旦被你编写了一个构造方法,那么不会再给你添加一个无参的构造方法了。

 */
public class StudentDemo {

    public static void main(String[] args) {
        //创建学生对象
        Student s = new Student("狗娃",18);
        Student s2 = new Student("狗剩",38);
        Student s3 = new Student();


//        System.out.println("学生的姓名:"+s.getName()+" 年龄:"+s.getAge());


    }
}

# 综合案例

# 封装学员信息

1646131393815.png

/*
           成员属性:学号(id)、姓名(name)、性别(sex)、年龄(age)
           成员方法:打印学员信息(print)、学习(study)

 */
public class Student {

    private int id;

    private String name;

    private String sex;

    private int age;


    //构造方法

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

    //无参构造方法
    public Student() {
    }

    //2. 生成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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>0 &&age<=120) {
            this.age = age;
        }else{
            System.out.println("年龄有误");
        }
    }

    //打印学生信息的方法
    public void print(){
        System.out.println("学号:"+this.id+"姓名:"+this.name+" 年龄:"+this.age+" 性别:"+this.sex);
    }

    //学习
    public void study(){
        System.out.println(name+ "good good study ,day day up ");
    }
}
public class StudentDemo {

    public static void main(String[] args) {
        Student s = new Student(110,"荣哥","男",22);
        //调用方法
        s.print();
        s.study();
    }
}

# 航班类设计

1646132050745.png

/*
成员属性:航班号(flightNum)、航空公司(airline)、起点站(from)、终点站(to)、票价(fare)
	成员方法:打印航空信息(print)


 */
public class Flight {

    private String flightNum;

    private String  airline;

    private String from;

    private String to;

    private double fare;

    //全参的构造方法
    public Flight(String flightNum, String airline, String from, String to, double fare) {
        this.flightNum = flightNum;
        this.airline = airline;
        this.from = from;
        this.to = to;
        this.fare = fare;
    }

    public String getFlightNum() {
        return flightNum;
    }

    public void setFlightNum(String flightNum) {
        this.flightNum = flightNum;
    }

    public String getAirline() {
        return airline;
    }

    public void setAirline(String airline) {
        this.airline = airline;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public double getFare() {
        return fare;
    }

    public void setFare(double fare) {
        this.fare = fare;
    }


    //打印航班信息
    public void print(){
        System.out.println("航班好:"+this.flightNum+" 航线:"+this.airline+" 出发点:"+this.from+" 终点:"+this.to+" 价格:"+this.fare);
    }
}
public class FlightDemo {

    public static void main(String[] args) {
        Flight f = new Flight("成都8633","成都-拉萨","成都","拉萨",88);
        f.print();
    }
}