Java---第五章(类和对象,方法带参)

Java---第五章

  • 一 类和对象
    • 类的由来:
    • 二者之间的关系
    • this关键字:
    • 构造方法
  • 二 方法带参
    • 构造方法带参:
    • 方法带参
    • 对象数组
    • 引用数据类型作为方法参数
    • 方法重载
    • 面向对象说明
    • 面向对象和面向过程的区别

Java---第五章(类和对象,方法带参)_第1张图片

一 类和对象

类的由来:

人们在日常生活中,经常会讲具有相同特征或者具有相同的行为的事物归为一类。
在Java中,用来描述这类事物的就是Java类,Java类就是这样诞生的,Java是一门以类为组织单元的语言
我们定义的Java类就是一种Java数据类型,该类型属于引用数据类型。

如何定义类:

public class 类名{

}

例如:
定义一个人

找出人类共同的特征:

    public class Person{
        public String name;//姓名
        public String sex;//性别
        public int age;//年龄
    }

找出人类共同的行为:
在Java中用方法描述行为,方法的定义语法如下:

//[]中内容表示可有可无

访问修饰符 返回值类型 方法名([参数列表]){
	[return 返回值;]
}

示例:

    public class Person{
        public String name;//姓名
        public String sex;//性别
        public int age;//年龄

        public void eat(){
            System.out.println("吃饭");
        }
        public void sleep(){
            System.out.println("睡觉");
        }
        public void work(){
            System.out.println("工作");
        }
    }

案例1:
定义一个计算器,计算器能够对两个数字进行加减乘除
分析:

  • 计算器可以接收两个数字和一个运算符
  • 计算器能够进行计算
    public class Caculator{
        public double number1;//接收数字1
        public double number2;//接收数字2
        public String operator;//接收运算符
        public void caculator(){//计算
            switch (operator){
                case "+":
                    System.out.println(number1 + number2);
                    break;
                case "-":
                    System.out.println(number1 - number2);
                    break;
                case "*":
                    System.out.println(number1 * number2);
                    break;
                case "/":
                    System.out.println(number1 / number2);
                    break;
            }
        }
    }

类图:
类图是描述类的结构,与流程图一样,简单直观

  • public修饰的属性和方法前要使用“+
  • private修饰的属性和方法前要使用“-

Java---第五章(类和对象,方法带参)_第2张图片

二者之间的关系

类是描述多个事物共有特征和行为的一个抽象体
对象是一个具体的事务,每一个属性和行为都是具体的
类是对象的集合体,类是用来构建具体的对象的

语法:

类名 对象名 = new 类名();
对象名.属性名 = 属性值;
public class study {
    public static void main(String[] args) {
        //这里p称为对象名,和数组名一样,本质都是变量
        Person p = new Person();//构建了一个具体的人
        p.name = "汴京城下君";
        p.sex = "男";
        p.age = 20;
    }
}

成员变量:
类中定义的变量就是成员变量。
成员变量的初始值:

类型 初始值
引用数据类型 null
整数 0
浮点数 0.0
boolean false
char ‘\u0000’

局部变量:
方法内部定义的变量。没有初始值,所以使用前要初始化

        public void eat(){
            String name;//报错,没有初始化
            System.out.println(name+"吃饭");
        }

当局部变量与成员变量重名时,局部变量的优先级更高。

public class Person{
    public String name;//姓名
    public String sex;//性别
    public int age;//年龄

    public void eat(){
        String name="张三";
        System.out.println(name+"吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
    public void work(){
        System.out.println("工作");
    }
}
public class ob {
    public static void main(String[] args) {

        //这里p称为对象名,和数组名一样,本质都是变量
        Person p = new Person();//构建了一个具体的人
        p.name = "汴京城下君";
        p.sex = "男";
        p.age = 20;
        p.eat();
    }
}

输出:
张三吃饭

this关键字:

在方法中,如果局部变量和成员变量同名,此时又想使用成员变量,怎么办呢?

public class Person{
    public String name;//姓名
    public String sex;//性别
    public int age;//年龄

    public void eat(){
        String name="张三";
        System.out.println(this.name+"吃饭");
    }
}
public class ob {
    public static void main(String[] args) {

        //这里p称为对象名,和数组名一样,本质都是变量
        Person p = new Person();//构建了一个具体的人
        p.name = "汴京城下君";
        p.sex = "男";
        p.age = 20;
        p.eat();
    }
}

输出:
汴京城下君吃饭

this还可以调用成员的方法:

public class Person{
    public String name;//姓名
    public String sex;//性别
    public int age;//年龄

    public void eat(){
        String name="张三";
        System.out.println(name+"吃饭");
        sleep();
       // 也相当于this.sleep();
    }
    public void sleep(){
        System.out.println("睡觉");
        work();
    }
    public void work(){
        System.out.println("工作");
        eat();
    }
}

构造方法

主要用于创建对象以及完成对象的属性初始化操作,构造方法不能被对象调用

语法:

//[]中内容可有可无
访问修饰符 类名([参数列表]){

}

示例:

public class Person{
    public String name;//姓名
    public String sex;//性别
    public int age;//年龄
    public Person(){
        this.name = "默认姓名";
        this.sex = "默认性别:男";
        this.age = 21;
    }
    public void eat(){
        String name="hello";
        System.out.println(age+"岁的"+sex+"性"+this.name+"吃饭");
    }
}
public class ob {
    public static void main(String[] args) {
        //这里p称为对象名,和数组名一样,本质都是变量
        Person p = new Person();//构建了一个具体的人
        p.eat();
        p.name = "汴京城下君";
        p.sex = "男";
        p.age = 20;
        p.eat();
    }
} 

输出:

21岁的默认性别:男性默认姓名吃饭
20岁的男性汴京城下君吃饭

二 方法带参

构造方法带参:

观察以下代码,有什么问题?

现有计算机类定义如下:

public class Computer{
    public String brand;//品牌
    public String type;//型号
    public int price;//价格
}

现要创建三个具体的计算机实例,如下:

public class ComputerTest{
    public static void main(String[] args){
        Computer c1 = new Computer();
        c1.brand = "联想";
        c1.type = "w1";
        c1.price = 5500;

        Computer c2 = new Computer();
        c2.brand = "联想";
        c2.type = "w2";
        c2.price = 6500;

        Computer c3 = new Computer();
        c3.brand = "联想";
        c3.type = "w3";
        c3.price = 7500;
    }
}

分析问题:

每创建一个对象,都会出现重复的对象的属性赋值,这样造成了大量的冗余代码
可以使用带参构造方法来优化

构造方法带参语法:/font>

访问修饰符 类名(数据类型1 变量1,数据类型2 变量2,.....数据类型n 变量n){

}

优化后:

带参构造方法

public class Computer{
    public String brand;//品牌
    public String type;//型号
    public int price;//价格
    public Computer(){}
    //如果在一个类中已经定义了带参数的构造方法,此时还想用无参构造方法,
    //那必须将无参构造方法也定义出来
    public Computer(String brand,String type,int price){
 //此时在类中定义了带参数的构造方法,那么编译器不会为这个类添加默认的无参构造方法
    }
}

构造新对象

public class ComputerTest{
    public static void main(String[] args){
        Computer c1 = new Computer("联想","w1",5500);
        Computer c2 = new Computer("联想","w2",6500);
        Computer c3 = new Computer("联想","w3",7500);
    }
}

案例1:
定义书籍类(名称,出版社,出版年月,价格)并用带参构造方法创建对象

public class Book{
    public String name;//书名
    public String publisher;//出版社
    public String publishtime;//出版时间
    public double price;//价格
    public Book(){}
    public Book(String name,String publisher,String publishtime, double price){
    }
}
public class BookTest{
    public static void main(String[] args){
        Book b1 = new Book("活着","北京十月文艺出版社","2017-06-01",32.5);
        Book b2 = new Book("动物农场","上海译文出版社","2010-08-01",28.4);
        Book b3 = new Book("瓦尔登湖","北京十月文艺出版社","2019-01-01",25.8);
        Book b4 = new Book("你当像鸟飞往你的山","南海出版公司","2019-11-01",34.2);
    }
}

方法带参

方法带参语法:

访问修饰符 返回值类型 方法名(数据类型1 变量名1,...数据类型n 变量名n{
	[return 返回值;]
}
//带参方法调用
对象名.方法名(实参1,实参2,...实参n);

案例1:
计算器

public class Calculator{
    public int number1;
    public int number2;
    public String operator;
    public int calculator(){
        //如果在一个方法中返回值类型不是void,那么在选择结构中,
        //必须每种情况都提供一个返回值
        switch (operator) {
            case "+": return number1 + number2;
            case "-": return number1 - number2;
            case "*": return number1 * number2;
            case "/": return number1 / number2;
            default:return 0;
        }
    }
}

案例2:
某商家共有30件啤酒,每件价格是72元,商家在3天内卖完这30件,请问每天买了多少钱?(利用上面计算器)

public class CalculatorTest{
    public static void main(String[] args){
        Calculator c = new Calculator();
        c.number1 = 30;
        c.number2 = 72;
        c.operator = "*";
        int total = c.calculator();
        c.number1 = total;
        c.number2 = 3;
        c.operator = "/";
        int avg = c.calculator();
        System.out.println("每天买了"+avg);
    }
}

存在什么问题?

依然是存在造成了大量的冗余代码

我们依然可以用带参构造方法进行代码优化,但是这样也是不符合生活的,
这里创建了两台计算器,生活中我们只需要一台即可。
利用带参方法进行优化:

public class Calculator{
    public int calculator(int number1,int number2,String operator){
        switch (operator) {
            case "+": return number1 + number2;
            case "-": return number1 - number2;
            case "*": return number1 * number2;
            case "/": return number1 / number2;
            default:return 0;
        }
    }
}
public class CalculatorTest{
    public static void main(String[] args){
        Calculator c = new Calculator();
        int total = c.calculator(30,72,"*");
        int avg = c.calculator(total,3,"/");
        System.out.println("每天买了"+avg);
    }
}

案例3:
求各数的阶乘

    public int factorial(int number){
        if(number==0) {
            return 1;
        }
        int result = 1;
       for(int i=1;i<=number;i++){
            result = result * i;
       }
       return result;
    }

案例4:
使用一个方法判断这个数是否为素数

public class Number{
    public boolean isPrime(int number){
        if(number==2) return true;
        for(int i=2;i*i<number;i++){
            if(number%i==0){
                return false;
            }
        }
        return true;
    }
}
public class NumberTest{
    public static void main(String[] args){
        Number tal = new Number();
        boolean result = tal.isPrime(5);
        System.out.println(result);
    }
}

对象数组

例如存储学生信息:

public class Student{
    public String name;
    public int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
}
public class StudentTest{
public static void main(String[] args){
    Student[] students = new Student[2];
    students[0] = new Student("张三",21);
    students[1] = new Student("李四",22);
    }
}

案例1:
使用数组存储学生选择的5门必修课程(课程编号,课程名称,学分)

public class Coures{
    public int code;
    public String name;
    public double scores;
    public Coures(int code,String name,double scores){
        this.code = code;
        this.name = name;
        this.scores = scores;
    }
}
public class CouresTest{
    public static void main(String[] args){
        Coures[] lessons = new Coures[5];
        lessons[0] = new Coures(31,"数据结构与算法",2);
        lessons[1] = new Coures(1,"Java",1.5);
        lessons[2] = new Coures(2,"C++",1.3);
        lessons[3] = new Coures(12,"Python",2.1);
        lessons[4] = new Coures(18,"MySQL",1.9);
    }
}

引用数据类型作为方法参数

案例分析:
某手机专卖店有100个手机展架,售货员现在依次向展架上摆放手机。请使用面向对象的设计思想描述这一过。(手机有品牌,型号和价格)

分析:

  • 这一过程涉及到的对象有两个,一个是手机,一个是售货员,因此我们需要为这两个对象构建类
  • 摆放手机是售货员的一个行为,因此需要用到方法
  • 100个手机展架都是摆放手机的,因此需要使用对象数组存储

代码:

public class Mobile {
    public String brand;
    public String type;
    public double price;
    public Mobile(String brand,String type,double price){
        this.brand = brand;
        this.type = type;
        this.price = price;
    }
}
public class Saler {
    public Mobile[] mobiles = new Mobile[100];
    public void playmobies(Mobile mobile){
        for(int i=0;i<mobiles.length;i++){
            if(mobiles[i]==null){
                mobiles[i] = mobile;
                break;
            }
        }
    }
}
public class MobileTest{
    public static void main(String[] args){
        Saler saler = new Saler();
        //调用售货员放手机
        saler.playmobies(new Mobile("小米","小米13",3499));
    }
}

案例1:
现有甲乙丙三个班级成绩统计如下:

  • 甲:80,72,85,67,50,76,95,49
  • 乙:77,90,92,89,67,94
  • 丙:99,87,95,93,88,78,85

现要求将每个班的成绩从高到低依次排序

import java.util.Arrays;
public class TeacherTest{
    public static void main(String[] args){
        int[] arr1 = {80,72,85,67,50,76,95,49};
        int[] arr2 = {77,90,92,89,67,94};
        int[] arr3 = {99,87,95,93,88,78,85};
        sortDesc(arr1);
        System.out.println(Arrays.toString(arr1));
        sortDesc(arr2);
        System.out.println(Arrays.toString(arr2));
        sortDesc(arr3);
        System.out.println(Arrays.toString(arr3));
    }
    public static void sortDesc(int[] arr){
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr.length-i-1;j++){
                if(arr[j] < arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}

基本数据类型传值时,传递的是值的拷贝

public class PassingValue{
    public static void main(String[] args){
        int a = 10;
        change(a);
        System.out.println(a);
    }
    public static void change(int number){
        number++;
    }
}

输出 :
10

引用数据类型传值时,传递的是对象在堆内存上的空间地址
Java---第五章(类和对象,方法带参)_第3张图片

方法重载

在同一个类中,方法名相同,参数列表不同的多个方法构成方法重载

示例:

public class Returnd{
    public int sum(int x,int y){
        return x+y;
    }
    public int sum(int x,int y,int c){
        return x+y+c;
    }
}

误区:

public class Teacher{
    public int sum(){
        return 1;
    }
    public void sum(){
        System.out.println("1");
    }
}

不是方法重载,因为方法名和参数列表都一样。
在同一个类中,不可能出现这种方法定义

面向对象说明

举例:
简易学生管理系统

  • 该过程涉及到的对象(事务)有两个:用户和菜单
  • 用户具有增删改查成绩的动作

面向对象和面向过程的区别

  • 面向对象的侧重点在对象上,需要利用对象的行为来完成过程的组装
  • 面向过程 的侧重点在过程的实现上

你可能感兴趣的:(Java,java,开发语言,编程学习)