Java面向对象基础(上)

一:类与对象

1.1、什么是类

从语法角度来说:

【修饰符】 class 类名{
    
}

从概念角度来说:

类:是一类具有相同特性的事物的抽象描述。与生活中对事物的分类是一个道理。

1.2、什么是对象

对象是这一类事物中的一个具体的个体、实体、实例。

1.3、类与对象的关系

从语法角度:类是创建对象的模板。

从概念来说:类是众多对象共同特征的描述。

1.4、创建对象的关键字:new

new 类名()  //匿名对象
类名  变量名/对象名 = new 类名(); //给对象取了一个名字

1.5、类的第一个成员:属性

(1)属性的声明

【修饰符】 class 类名{
    //属性
    【修饰符】 数据类型  属性名;
}
public class Employee {//员工类
    //属性
    public String name;
    public int age;
    public double salary;
    
}

(2)在其他类中如何访问这些属性

//(1)先创建对象
类名  变量名/对象名 = new 类名();

//(2)对象名.属性
对象名.属性 = 值;
System.out.println(对象名.属性)

//TestEmployee类是作为测试类,作为程序的入口
public class TestEmployee {
    public static void main(String[] args) {
        //第一步:创建一个Employee类的对象
        Employee emp = new Employee();
        Employee emp2 = new Employee();

        //第二步:通过对象.属性的方式访问
        emp.name ="张三";
        emp.age = 23;
        emp.salary = 15000;

        System.out.println("员工对象emp的信息:姓名:" + emp.name +",年龄:" + emp.age +",薪资:" + emp.salary);
        System.out.println("员工对象emp2的信息:姓名:" + emp2.name +",年龄:" + emp2.age +",薪资:" + emp2.salary);
    }
}

(3)属性的特点

  • 每一个对象的属性是独立的

  • 对象的属性有默认值

    • byte,short,int,long:默认值是0

    • float,double:默认值是0.0

    • char:默认值 编码值为0的空字符

    • boolean:默认值:false

    • 引用数据类型:null

(4)属性值存储在堆,new出来的都在堆中存储

二、类的成员之一:成员变量(非常重要)

2.1 成员变量的分类

根据有没有static修饰,成员变量可以分为两类:

(1)静态成员变量,简称静态变量,又称为类变量

(2)非静态成员变量,简称实例变量,俗称属性

【修饰符】 class 类名{
    【其他修饰符】 static 数据类型 变量名; //静态变量
    //属性
    【修饰符】 数据类型  属性名; //实例变量
}

2.2 静态变量与实例变量的区别

  • 静态变量:它的值是整个类“共享的”,==不推荐==(但是不是说不可以)通过“对象名.静态变量”的方式进行访问,==推荐使用“类名.静态变量”==的方式进行访问

  • 实例变量:它的值是每一个对象“独立的”,只能是通过“对象名.实例变量”的方式进行访问

BankAccount类
public class BankAccount {//Account账户,银行账号
    public static double rate;//rate,利率  静态变量
    public String id;//id,卡号             实例变量
    public double balance;//balance,余额   实例变量
}

TestBankAccount类
public class TestBankAccount {
    public static void main(String[] args) {
        //第一步:创建BankAccount类的对象
        BankAccount b1 = new BankAccount();

        //第二步:访问b1对象的属性
        b1.id = "1111111";
        b1.balance = 5000;

//        BankAccount.id = "333333";//报错
        BankAccount.rate = 0.035;

        System.out.println("b1账号的信息,卡号:" + b1.id
                +",余额:" + b1.balance
                +",b1的利率:" + b1.rate
                +",BankAccount的利率:" + BankAccount.rate);
        //b1账号的信息,卡号:1111111,余额:5000.0,b1的利率:0.035,BankAccount的利率:0.035

        BankAccount b2 = new BankAccount();
        b2.id = "22222222";
        b2.balance = 8000;
        b2.rate = 0.04;

        System.out.println("b1账号的信息,卡号:" + b1.id
                +",余额:" + b1.balance
                +",b1的利率:" + b1.rate
                +",BankAccount的利率:" + BankAccount.rate);
//        b1账号的信息,卡号:1111111,余额:5000.0,b1的利率:0.04,BankAccount的利率:0.04

        System.out.println("b2账号的信息,卡号:" + b2.id
                +",余额:" + b2.balance
                +",b2的利率:" + b2.rate
                +",BankAccount的利率:" + BankAccount.rate);
//        b2账号的信息,卡号:22222222,余额:8000.0,b2的利率:0.04,BankAccount的利率:0.04
    }
}

2.3 静态变量与实例变量的内存分析

  • 静态变量先初始化,它在类加载完就进行了初始化,它的值存储在方法区,整个类包括所有对象“共享的”

  • 实例变量后初始化,在new对象时才会初始化,每一个对象都会初始化一次,它的值存储在堆中,每一个对象都是“独立的”

Chinese类
public class Chinese {//中国人
    public static String country;//国家名,共享
    public String name;//姓名,独立
    public int age;//年龄,独立
}
TestChinese类
public class TestChinese {
    public static void main(String[] args) {
        System.out.println(Chinese.country);//null

        Chinese.country = "中国";

        Chinese c1 = new Chinese();
        c1.name = "张三";
        c1.age = 23;

        c1.country = "中华人民共和国";


        Chinese c2 = new Chinese();
        c2.name ="李四";
        c2.age = 24;
    }
}

2.4 引用数据类型的成员变量

需求:

(1)声明一个MyDate类型,有属性:年,月,日

(2)声明另一个Employee类型,有属性:姓名(String类型),生日(MyDate类型)

(3)在TestEmployee测试类中的main中,创建两个员工对象,并为他们的姓名和生日赋值,并显示

MyDate类
//(1)声明一个MyDate类型,有属性:年,月,日
public class MyDate {
    public int year;
    public int month;
    public int day;
}
Employee类
//(2)声明另一个Employee类型,有属性:姓名(String类型),生日(MyDate类型)
public class Employee {
    public String name;

    //只要是类,就可以在Java中当成数据类型
    public MyDate birthday;
}
TestEmployee类
public class TestEmployee {
    public static void main(String[] args) {
        //第一步:创建员工Employee类的对象
        Employee e1 = new Employee();

        //第二步:给e1对象的属性赋值
        e1.name = "张三";
        //因为String比较特殊,它可以像基本数据类型一样,直接赋字符串的值,
        //看不出来"张三"是一个对象
        //e1.birthday = "1995-5-1";
        //报错,"1995-5-1"是字符串值,而birthday是MyDate类型

        e1.birthday = new MyDate();
        //注意:birthday是除了字符串之外的其他引用数据类型
        //那么给它赋值必须赋一个对应类型的“对象”,否则会报错

        e1.birthday.year = 1995;
        e1.birthday.month = 5;
        e1.birthday.day = 1;

        System.out.println("e1员工的信息:姓名:" + e1.name
                +",生日:" + e1.birthday);
        //e1员工的信息:姓名:张三,生日:MyDate@16b98e56
        //除了字符串之外(字符串比较特殊),其他对象,默认打印出来的都是 虚拟首地址

        System.out.println("e1员工的信息:姓名:" + e1.name
                +",生日:" + e1.birthday.year+"年"
                + e1.birthday.month+"月"
                + e1.birthday.day+"日");
        //e1员工的信息:姓名:张三,生日:1995年5月1日

        Employee e2 = new Employee();
        e2.name = "李四";
        e2.birthday = new MyDate();
        //没有这一句,编译没有问题,但是运行下面的代码会报NullPointerException
        e2.birthday.year = 2000;
        e2.birthday.month = 8;
        e2.birthday.day = 9;
        System.out.println("e2员工的信息:姓名:" + e2.name
                +",生日:" + e2.birthday.year+"年"
                + e2.birthday.month+"月"
                + e2.birthday.day+"日");

        Employee e3 = new Employee();
        e3.name = "王五";
        MyDate my = new MyDate();
        my.year = 2001;
        my.month = 6;
        my.day = 9;
        e3.birthday = my;

        e3.birthday.day = 10;

        System.out.println("e3员工的信息:姓名:" + e3.name
                +",生日:" + e3.birthday.year+"年"
                + e3.birthday.month+"月"
                + e3.birthday.day+"日");

        System.out.println("my对象:" + my.year+"年" + my.month +"月" + my.day+"日");
    }
}
图片1234:能.出什么

图片:怎么看错误

引用数据类型的属性内存图分析

2.5 方法的参数传递机制(再谈引用数据类型)

(1)参数是基本数据类型

实参给形参传什么值?实参给形参传递的是数据值的副本。

形参的修改对实参有什么影响?形参的修改对实参没有影响。

(2)参数是引用数据类型

实参给形参传什么值?实参给形参传递的是首地址的副本。

形参的修改对实参有什么影响?

  • 形参数组对元素的修改相当于实参数组自己修改的元素。

  • 形参对象对属性的修改相当于实参对象自己修改属性。

//(1)声明一个MyDate类型,有属性:年,月,日
public class MyDate {
    public int year;
    public int month;
    public int day;
}
public class TestParamPassValue {
    public static void main(String[] args) {
        MyDate date = new MyDate();
        System.out.println(date.year + "年" + date.month + "月" + date.day +"日");
        //0年0月0日

        change(date);//(date)实参  给形参 (MyDate my)的是对象的首地址的副本。此时形参对对象的属性做了修改,相当于实参自己修改了属性

        System.out.println(date.year + "年" + date.month + "月" + date.day+"日");
        //0年0月1日
    }

    public static void change(MyDate my) {//(MyDate my)是形参,是引用数据类型
        my.day++; //修改了my对象的属性day
    }
}

 

2.6 方法的返回值类型(再谈引用数据类型)

方法的返回值类型分为3种情况:

  • void:表示无返回值

  • 有返回值

    • 8种基本数据类型:方法返回的是数据值的副本

    • 引用数据类型:方法返回的是对象的首地址(无论是数组还是普通的类对象)

//(1)声明一个MyDate类型,有属性:年,月,日
public class MyDate {
    public int year;
    public int month;
    public int day;
}

 

public class TestReturnValue {
    public static void main(String[] args) {
        MyDate date = create(2000,5,1);
        System.out.println(date.year + "年" + date.month + "月" + date.day +"日");
        //2000年5月1日
    }

    public static MyDate create(int year, int month, int day){
        MyDate my = new MyDate();
        my.year = year;
        my.month = month;
        my.day = day;
        return my;
    }
}

三、类的成员之二:成员方法(非常重要)

3.1 成员方法的分类

根据有没有static修饰,成员方法可以分为两类:

(1)静态方法:有static修饰,又称为类方法

(2)非静态方法:没有static修饰,又称为实例方法

【修饰符】 class 类名{
    【其他修饰符】 static 返回值类型  方法名(【形参列表】){ //静态方法,类方法
        【方法体语句;】
    }
    
    【其他修饰符】 返回值类型  方法名(【形参列表】){ //非静态方法,实例方法
        【方法体语句;】
    }
}

3.2 静态方法与非静态方法的区别

1、在其他类中调用这个方法的方式不同

  • 静态方法:在其他类中 ,==推荐==使用“类名.静态方法”的方式调用,==不推荐==“对象名.静态方法”的方式调用。

  • 非静态方法:在其他类中,只能是通过“对象名.非静态方法”的方式进行调用。

public class Demo {
    public static void m1(){
        System.out.println("m1是一个静态方法");
    }

    public void m2(){
        System.out.println("m2是一个非静态方法");
    }
}

 

​
public class TestDemo {
    public static void main(String[] args) {
        Demo.m1();//静态方法,推荐使用“类名.静态方法”调用

        Demo d = new Demo();
        d.m2();//非静态方法,只能通过“对象.非静态方法”调用
        d.m1();//不推荐,静态方法,通过“对象.静态方法”调用
    }
}
​

2、在方法中使用本类的其他成员的限制不同

  • 静态方法:不可以访问本类的其他的非静态成员,包括属性以及其他的非静态方法等。也不可以出现this单词。

    • 静态方法中“只能”访问本类的其他静态成员。

  • 非静态方法:可以直接访问本类的所有成员,包括静态的和非静态的,包括成员变量,也包括成员方法。因为静态的东西是本类以及本类所有对象共享。

public class Account {
    //成员变量
    public static double rate;//静态变量
    public String id;//实例变量,属性
    public double balance;//实例变量,属性

/*    public void method(){//调用它变的麻烦了,需要new对象
        System.out.println("rate =" + rate);
    }*/

    //成员方法
    public static void showRate(){
        System.out.println("现在的利率值:" + rate);
//        System.out.println("当前" + id + "  的利息:" + balance * rate);//报错
//        System.out.println("当前" + this.id + "  的利息:" + this.balance * rate);//报错
        //因为balance是对象有关,必须有对象,才有balance的值
        //而调用showRate方法时,根本没有 当前对象 的概念
    }

    public void showInterest(){
        //粗糙算 利息 = 余额 * 利率
        System.out.println("当前" + id + "  的利息:" + balance * rate);
        System.out.println("当前" + this.id + "  的利息:" + this.balance * rate);
        //当前对象 this ,这里指的是调用这个方法的对象
    }
}

 

public class TestAccount {
    public static void main(String[] args) {
        Account.rate = 0.035;
        Account.showRate();//此时没有创建Account类的对象

        Account a1 = new Account();
        a1.id = "111111";
        a1.balance = 5000;
        a1.showInterest();//先创建了一个Account对象,才调用showInterest()方法
        //当前111111  的利息:175.00000000000003

        Account a2 = new Account();
        a2.id = "22222";
        a2.balance = 8000;
        a2.showInterest();
        //当前22222  的利息:280.0

        a1.showRate();
        //虽然这么写,编译器仍然处理为 Account.showRate();
        //所以,在showRate()根本不可能有当前对象的概念

       /* Account a3 = new Account();
        a3.method();*/
    }
}

3、思考题:一个方法什么时候该声明为静态的,什么时候该声明为非静态的?

原则(非常重要):

  • 如果在这个方法的方法体中,涉及到 访问本类的 其他 “非静态”成员,那么这个方法“只能”声明为 非静态的。

  • 如果在这个方法的方法体中,==不 涉及== 到访问 本类的 其他 “非静态”成员,那么这个方法既可以声明为静态的,也可以声明为非静态。此时一般都是声明静态的,因为这样的方法,调用更方便。

3.3 成员变量与成员方法的结合

案例一:圆

需求:

  • 声明一个代表圆的类Circle,包含属性 radius(半径)

  • 声明一个测试类,创建圆对象,求圆的面积和周长

 

public class Circle {
    //成员变量,因为是非静态的,又称为实例变量,俗称属性
    public double radius;//半径

    /*
    因为所有的圆对象,都具有求面积的功能,这是所有圆对象共同的特征。
    类的概念:一类具有相同特性的事物的抽象描述。换句话说,这个类中就应该体现这个类的所有对象的共同特征。
     */
    public double area(){//求面积
//        return Math.PI * this.radius * this.radius;
        return Math.PI * radius * radius;
        //this代表当前对象,调用这个方法的对象,每一个圆的面积值都是独立,用各自自己的半径值来计算的。this可以省略
    }

    public double perimeter(){//求周长
//        return 2 * Math.PI * this.radius;
        return 2 * Math.PI * radius;
    }

    public String getInfo(){
//        return "半径:" + this.radius +",面积:" + this.area() +",周长:" + this.perimeter();
        return "半径:" + radius +",面积:" + area() +",周长:" + perimeter();
    }
}

public class TestCircle {
    public static void main(String[] args) {
        //创建Circle的对象
        Circle c1 = new Circle();
        c1.radius = 2.5;

        //Math类中有一个常量PI,代表圆周率
//        double a1 = Math.PI * c1.radius * c1.radius;
//        double a1 = c1.area();
//        double p1 = 2 * Math.PI * c1.radius;
//        double p1 = c1.perimeter();
//        System.out.println("c1的信息:半径:" + c1.radius +",面积:" + a1 + ",周长:" + p1);
        System.out.println("c1的信息:" + c1.getInfo());

        System.out.println("================");
        //创建Circle的对象
        Circle c2 = new Circle();
        c2.radius = 3.0;

        //Math类中有一个常量PI,代表圆周率
//        double a2 = Math.PI * c2.radius * c2.radius;
//        double a2 = c2.area();
//        double p2 = 2 * Math.PI * c2.radius;
//        double p2 = c2.perimeter();
//        System.out.println("c2的信息:半径:" + c2.radius +",面积:" + a2 + ",周长:" + p2);
        System.out.println("c2的信息:" + c2.getInfo());

    }
}

案例二:日期和员工

需求:

(1)声明一个MyDate类型,有属性:年,月,日

(2)声明另一个Employee类型,有属性:姓名(String类型),生日(MyDate类型)

(3)在TestEmployee测试类中的main中,创建两个员工对象,并为他们的姓名和生日赋值,并显示

版本1:请看第2.4小节
//(1)声明一个MyDate类型,有属性:年,月,日
public class MyDate {
    public int year;
    public int month;
    public int day;
}
//(2)声明另一个Employee类型,有属性:姓名(String类型),生日(MyDate类型)
public class Employee {
    public String name;

    //只要是类,就可以在Java中当成数据类型
    public MyDate birthday;
}
public class TestEmployees {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        e1.name = "张三";
        e1.birthday = new MyDate();
        e1.birthday.year = 1996;
        e1.birthday.month = 8;
        e1.birthday.day = 9;
        System.out.println("e1的信息:姓名:" + e1.name+",生日:" + e1.birthday.year+"年" +e1.birthday.month+"月" +e1.birthday.day+"日");

        System.out.println("======================");

        Employee e2 = new Employee();
        e2.name = "张三";
        e2.birthday = new MyDate();
        e2.birthday.year = 1994;
        e2.birthday.month = 5;
        e2.birthday.day = 1;
        System.out.println("e2的信息:姓名:" + e2.name+",生日:" + e2.birthday.year+"年" +e2.birthday.month+"月" +e2.birthday.day+"日");

        System.out.println("==================");
        MyDate today = new MyDate();
        today.year = 2024;
        today.month = 4;
        today.day = 14;
        System.out.println("今天的日期:" + today.year +"年" + today.month+"月" + today.day+"日");
    }
}
版本2:把重复代码抽取成方法
public class MyDate {
    public int year;
    public int month;
    public int day;

    //这个方法的作用 :是为MyDate类型的对象的year, month, day属性赋值的
    public void setDate(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;

        //左边的this此时不可以省略
        //this.变量 代表的是当前对象.属性,没有加this.的,在这里是局部变量,形参
    }

    //这个方法的作用:通过一个MyDate类型的对象,获取该对象的year, month, day属性值
    public String getDateInfo(){
//        return this.year +"年" + this.month+"月" + this.day+"日";
        return year +"年" + month+"月" + day+"日";
    }
}
public class Employee {
    public String name;
    public MyDate birthday;

    //这个方法的作用,为一个员工对象,设置 birthday属性值
    public void setBirthday(int year, int month, int day){
//        this.birthday = new MyDate();
        /*this.birthday.year = year;
        this.birthday.month = month;
        this.birthday.day = day;*/
//        this.birthday.setDate(year, month, day);
        
        //this是员工类的对象,e1或e2
        birthday = new MyDate();
        birthday.setDate(year, month, day);
    }

    //这个方法的作用:根据一个员工对象,获取这个员工对象的姓名和生日属性值
    public String getInfo(){
//        return "姓名:" + this.name+",生日:" + this.birthday.year+"年" +this.birthday.month+"月" +this.birthday.day+"日";
//        return "姓名:" + name+",生日:" + birthday.year+"年" + birthday.month +"月" + birthday.day+"日";
        return "姓名:" + name+",生日:" + birthday.getDateInfo();
    }
}
public class Employee {
    public String name;
    public MyDate birthday;

    //这个方法的作用,为一个员工对象,设置 birthday属性值
    public void setBirthday(int year, int month, int day){
//        this.birthday = new MyDate();
        /*this.birthday.year = year;
        this.birthday.month = month;
        this.birthday.day = day;*/
//        this.birthday.setDate(year, month, day);
        
        //this是员工类的对象,e1或e2
        birthday = new MyDate();
        birthday.setDate(year, month, day);
    }

    //这个方法的作用:根据一个员工对象,获取这个员工对象的姓名和生日属性值
    public String getInfo(){
//        return "姓名:" + this.name+",生日:" + this.birthday.year+"年" +this.birthday.month+"月" +this.birthday.day+"日";
//        return "姓名:" + name+",生日:" + birthday.year+"年" + birthday.month +"月" + birthday.day+"日";
        return "姓名:" + name+",生日:" + birthday.getDateInfo();
    }
}

 

public class TestEmployees2 {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        e1.name = "张三";
        e1.setBirthday(1996,8,9);
        System.out.println("e1的信息:" + e1.getInfo());

        System.out.println("======================");

        Employee e2 = new Employee();
        e2.name = "张三";
        e2.setBirthday(1994,5,1);
        System.out.println("e2的信息" +e2.getInfo());

        System.out.println("==================");
        MyDate today = new MyDate();
        today.setDate(2024,4,14);
        System.out.println("今天的日期:" + today.getDateInfo());
    }
}

四、对象数组

这里只讨论一维对象数组,关于二维对象数组,等熟练使用一维对象数组之后,之后根据现有知识自然可以做到举一反三。

4.1 对象数组的声明和初始化

1、声明

元素的类型[] 数组名; //此时数组的元素是一个类的对象,所以元素类型此时是一个类的类型
类类型[] 数组名; //声明了一个对象数组
例如:存储一组员工对象
    员工类:Employee
    员工数组:Employee[] employees;

 

例如:存储一组圆对象
    圆类:Circle
    圆数组:Circle[] circles;
例如:存储一组矩形对象
    矩形类:Rectangle
    矩形数组:Rectangle[] all;

2、初始化

(1)静态初始化
//元素的类型[] 数组名 = {元素值1, 元素值2, ......};
类类型[] 数组名 = {对象1, 对象2, ......};
(2)动态初始化
//元素的类型[] 数组名 = new 元素的类型[长度];
类类型[] 数组名 = new 类类型[长度];

数组名[下标] = new 类类名(); //创建元素对象

(3)示例代码
public class Rectangle {//矩形
    //成员变量,属性
    public double length;
    public double width;

    //成员方法
    public double area(){//求面积的方法
        return length * width;
    }

    public double perimeter(){//求周长
        return 2 * (length + width);
    }

    public String getInfo(){
        return "长:" + length +",宽:" + width +",面积:" + area() +",周长:" + perimeter();
    }
}

静态初始化示例代码:

public class TestRectangle {
    public static void main(String[] args) {
        /*
        例如:存储一组矩形对象
    矩形类:Rectangle
    矩形数组:Rectangle[] all;
         */
//        Rectangle[] all = new Rectangle[] {new Rectangle(), new Rectangle(), new Rectangle()};
        Rectangle[] all = {new Rectangle(), new Rectangle(), new Rectangle()};
        //上面数组中存储了3个矩形对象

/*        for (int i = 0; i < all.length; i++) {
            System.out.println(all[i]);
        }*/
        /*
        array.Rectangle@4eec7777
        array.Rectangle@3b07d329
        array.Rectangle@41629346
         */

        //all[下标]是Rectangle类型的对象,
        // 就可以通过 all[i]. 出 Rectangle里面定义的成员(包括属性和方法)
         all[0].length = 8;
         all[0].width = 5;

         all[1].length = 6;
         all[1].width = 3;

         all[2].length = 9;
         all[2].width = 4;


        for (int i = 0; i < all.length; i++) {
            //all[i]是Rectangle类型的对象,就可以通过 all[i]. 出 Rectangle里面定义的成员(包括属性和方法)
            System.out.println(all[i].getInfo());
        }
    }
}

动态初始化示例代码:

public class TestRectangle2 {
    public static void main(String[] args) {
        Rectangle[] all = new Rectangle[3];

        all[0] = new Rectangle();
        all[0].length = 8;
        all[0].width = 5;

        all[1] = new Rectangle();
        all[1].length = 6;
        all[1].width = 3;

        all[2] = new Rectangle();
        all[2].length = 9;
        all[2].width = 4;


        for (int i = 0; i < all.length; i++) {
            //all[i]是Rectangle类型的对象,就可以通过 all[i]. 出 Rectangle里面定义的成员(包括属性和方法)
            System.out.println(all[i].getInfo());
        }
    }
}

3、遍历

for(int i=0; i<数组名.length; i++){
    数组名[i]代表一个元素,只不过此时这个元素是一个对象。既然是一个对象,就可以 数组名[i].属性  或 数组名[i].方法。
}

4.2 对象数组的内存分析

4.3 对象数组的排序(延伸)

public class TestRectangle3 {
    public static void main(String[] args) {
        Rectangle[] all = new Rectangle[3];

        all[0] = new Rectangle();
        all[0].length = 8;
        all[0].width = 5;

        all[1] = new Rectangle();
        all[1].length = 6;
        all[1].width = 3;

        all[2] = new Rectangle();
        all[2].length = 9;
        all[2].width = 4;

        //排序之前:
        System.out.println("排序之前:");
        for (int i = 0; i < all.length; i++) {
            System.out.println(all[i].getInfo());
        }

        //按照面积排序;从小到大排序
        //冒泡排序
        for (int i = 0; i < all.length - 1; i++) {//循环轮数
            //内循环循环次数
            for(int j=0; j<all.length-1-i; j++){
//                if(all[j] > all[j+1]){//报错,因为all[j]和all[j+1]存储的是对象的首地址,地址是无法比较大小的
                if(all[j].area() > all[j+1].area()){//需要比较对象的属性值,或面积值等
                    //交换all[j]和all[j]里面的对象
                    Rectangle temp = all[j];
                    all[j] = all[j+1];
                    all[j+1] = temp;
                }
            }
        }

        //排序后的结果输出
        System.out.println("按照面积从小到大排序之后:");
        for (int i = 0; i < all.length; i++) {
            System.out.println(all[i].getInfo());
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值