Java面向对象之Object类的使用

1 - Object类的介绍

/*
java.lang.Object类

1 - Object类是所有Java类的根父

2 - 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object

3 - Object类中的功能(属性、方法)就具有通用性

  属性:无

  方法:equals() / toString() / getClass() / hashCose() / clone() / finalize() / wait() / notify() / notfyAll()等

4 - Object类只声明了一个空参构造器
*/

2 - Object类的主要结构

3 - 操作符==与equals方法的区别

/*
面试题:== 和 equals() 的区别

1 - 回顾 == 的使用:

  ==:运算符

  1 - 可以使用在基本数据类型变量和引用数据类型变量

  2 - 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)

  3 - 如果比较的是引用数据类型变量:比较两个对象的地址值是否相等,即两个引用是否指向同一个对象实体

2 - equals()方法的使用:

  1-是一个方法,而非运算符

  2-只能适用于引用数据类型

  3-Object类中equals()的定义:

     public boolean equals(Object anObject) {

      if (this == anObject) {

        return true;

      }

    }

    说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相等,即两个引用是否指向同一个对象实体

3-像String,Date,File,包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。

4-通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写

*/

public class EqualTests {
    public static void main(String[] args) {
        int i = 10;
        int j = 10;
        System.out.println(i == j); // true
        double d = 10.0;
        System.out.println(j == d); // true
        char c = 10;
        System.out.println(c == d); // true
        
        String s1 = new String("A");
        String s2 = new String("A");
        System.out.println(s1 == s2); // false
        
        System.out.println(s1.equals(s2)); // true
        
        MyObject obj1 = new MyObject("alex", 22);
        MyObject obj2 = new MyObject("alex", 22);
        System.out.println(obj1.equals(obj2)); // true
    }
}

class MyObject{
    String name;
    int age;
    
    
    public MyObject() {
        super();
    }
    public MyObject(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    // 手动重写
    /*
    // Object类中的equals()进行重写,使其实现我们需要的功能
    // 重写原则:比较两个对象的实体内容(即:name和age)是否相同
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        // return super.equals(obj);
        if(this == obj) {
            return true;
        }
        if(obj instanceof MyObject) {
            MyObject myObject = (MyObject)obj;
            if(myObject.age == this.age && myObject.name.equals(this.name)) {
                return true;
            }
            return false;
        }
        return false;
    }
    */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    // 自动生成
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyObject other = (MyObject) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
代码验证及equals的重写

4 - equals重写的练习

/*
1.编写Order类,有int型的orderId,String型的orderName,相应的 getter()和setter()方法,两个参数的构造器,重写父类的equals()方法: public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等
*/

package com.lzh.exer1;
/*
 * 1.编写Order类,有int型的orderId,String型的orderName,相应的 getter()和setter()方法,两个参数的构造器,重写父类的equals()方法: public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等
 */
public class OrderTest {
    public static void main(String[] args) {
        Order order1 = new Order(2, "alex");
        Order order2 = new Order(2, "alex");
        
        System.out.println(order1 == order2); // false
        System.out.println(order1.equals(order2)); // true
    }
}

class Order{
    private int orderId;
    private String name;
    
    public int getOrderId() {
        return orderId;
    }
    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    // 构造器
    public Order() {
        super();
    }
    public Order(int orderId,String name) {
        super();
        this.orderId = orderId;
        this.name = name;
    }
    
    // 手动重写equals方法
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        // return super.equals(obj);
        if(this == obj) {
            return true;
        }
        if(obj instanceof Order) {
            Order order = (Order)obj;
            return this.orderId == order.orderId && this.name.equals(order.name);
        }
        return false;
    }
}
OrderTest.java

5 - Object类toString()的使用

/*
Object类toString()的使用

1 - 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()

2 - Object类中toString()的定义:

   public String toString() {

    return getClass().getName() + "@" + Integer.toHexString(hashCode());

   }

3 - 像String,Date,File,包装类等都重写了Object类中的 toString()方法。使得在调用对象的toString()时,返回"实体内容"信息

4-自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"

*/

package com.lzh.java1;
/*
 * Object类toString()的使用
 * 1-当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
 * 
 * 2-Object类中toString()的定义:
 *         public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
 *      }
 * 3-像String,Date,File,包装类等都重写了Object类中的 toString()方法。使得在调用对象的toString()时,返回"实体内容"信息
 * 4-自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"
 * 
 */
public class toStringTest {
    public static void main(String[] args) {
        Customer c = new Customer("alex", 22);
        System.out.println(c.toString()); // com.lzh.java1.Customer@5305068a
        // System.out.println(c);
        
        // String类型重写过toString()
        String name = new String("alex");
        System.out.println(name); // alex

    }
}

class Customer{
    String name;
    int age;
    
    public Customer(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    // 手动实现
//    @Override
//    public String toString() {
//        // TODO Auto-generated method stub
//        // 重写toString()
//        return "Customer"+"{name:"+name+",age:"+age+"}";
//    }

    // 自动生成
    @Override
    public String toString() {
        return "Customer [name=" + name + ", age=" + age + "]";
    }
}
toStringTest.java

6 - Java中的JUnit单元测试的使用

/*
Java中的JUnit单元测试

步骤:

    1-选中当前工程 -> 右键选择:build path -> add libraries -> JUnit 4 -> 下一步

    2-创建Java类,进行单元测试,此时的Java类要求:①此类是public的。②此类提供公共的无参构造器

    3-在此类中声明单元测试方法。此时单元测试方法:方法的权限是public,没有返回值,没有形参

    4-此单元测试方法需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;

    5-声明好单元测试方法以后,就可以在方法体内测试相关的代码

    6-写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test

说明:

    ①如果执行结果没有任何异常:绿条

    ②如果执行结果没有任何异常:红条
*/

package com.lzh.java1;

import org.junit.Test;

/*
 * Java中的JUnit单元测试
 * 步骤:
 *     1-选中当前工程 -> 右键选择:build path -> add libraries -> JUnit 4 -> 下一步
 *     2-创建Java类,进行单元测试,此时的Java类要求:①此类是public的。②此类提供公共的无参构造器
 *     3-在此类中声明单元测试方法。此时单元测试方法:方法的权限是public,没有返回值,没有形参
 *     4-此单元测试方法需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
 *     
 *     5-声明好单元测试方法以后,就可以在方法体内测试相关的代码
 *     6-写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
 * 
 * 说明:
 *     ①如果执行结果没有任何异常:绿条
 *     ②如果执行结果没有任何异常:红条
 */
public class JUnitTest {
//    public static void main(String[] args) {
//        JUnitTest test = new JUnitTest();
//        test.testEquals();
//    }
    int number = 10;
    @Test
    public void testEquals() {
        String s1 = "aa";
        String s2 = "aa";
        System.out.println(s1.equals(s2)); // true
        
        System.out.println(number); // 10
    }
    @Test
    public void testToString() {
        String s = "李白";
        System.out.println(s.toString()); // 李白
    }
}
JUnitTest.java

7 - 包装类(wrapper)的使用

/*
包装类的使用

1 - Java提供了8中基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征

2 - 掌握的:基本数据类型、包装类、String三者之间的相互转换

3-JDK 5.0新增特性:自动装箱与自动拆箱

  自动装箱:

       int num = 10;

       Integer int1 = num; // 自动装箱

       boolean b1 = true;

       Boolean b2 = b1; // 自动装箱

  自动拆箱:

       Integer int2 = new Integer(12);

       int number = int2; // 自动拆箱
*/

package com.lzh.java1;

import org.junit.Test;

/*
 * 包装类的使用
 * 1-Java提供了8中基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
 * 2-掌握的:基本数据类型、包装类、String三者之间的相互转换
 * 
 * 3-JDK 5.0新增特性:自动装箱与自动拆箱
 *     自动装箱:
 *       int num = 10;
 *       Integer int1 = num; // 自动装箱
 * 
 *       boolean b1 = true;
 *       Boolean b2 = b1; // 自动装箱
 *     自动拆箱:
 *       Integer int2 = new Integer(12);
 *       int number = int2; // 自动拆箱
 * 
 */
public class WrapperTest {
    // 基本数据类型 -> 包装类:调用包装类的构造器
    @Test
    public void test1() {
        int num1 = 10;
        // System.out.println(num1.toString());
        Integer inter = (Integer)num1;
        System.out.println(inter.toString()); // 10
        
        Integer num2 = new Integer("20");
        System.out.println(num2.toString()); // 20
        
//        Integer num3 = new Integer("20abc"); 异常
//        System.out.println(num3.toString());
        
        Float f1 = new Float("12.3");
        System.out.println(f1.toString()); // 12.3
        
        Boolean b1 = new Boolean("TrUe");
        System.out.println(b1); // true
        
        Boolean b2 = new Boolean("true123");
        System.out.println(b2); // false
        
        Person p = new Person();
        System.out.println(p.isMale); // false
        System.out.println(p.isFemal); // null
    }
    
    // 包装类 -> 基本数据类型:调用包装类的xxx的xxxValue()
    @Test
    public void test2() {
        Integer int1 = new Integer(12);
        int num = int1.intValue();
        System.out.println(num+8); // 20
        
        Float f1 = new Float(2.5);
        float num2 = f1.floatValue();
        System.out.println(num2+0.5); // 3.0
    }
    
    // 基本数据类型、包装类 -> String类型:调用String重载的valueOf()
    @Test
    public void test3() {
        // 方式1:连接运算
        int number1 = 10;
        String s = number1 + "";
        
        // 方式2:调用String的valueOf([类型变量])
        float f1 = 12.5f;
        String s2 = String.valueOf(f1); // "12.5"
        System.out.println(s2);
        
        Double d1 = new Double(2.5);
        String s3 = String.valueOf(d1); // 自动拆箱
        System.out.println(s3); // 2.5
    }
    
    // String类型 -> 基本数据类型、包装类:调用包装类的parseXxx()
    @Test
    public void test4() {
        String str = "99";
        // 错误示例
        // int num = (int)str;
        // Integer int1 = (Integer)str1;
        
        int num1 = Integer.parseInt(str);
        System.out.println(num1 + 1); // 100
    }
}

class Person{
    boolean isMale;
    Boolean isFemal;
}
三者之间的转换

图解

/*
包装类的使用面试题
*/

package com.lzh.interview;

import org.junit.Test;

/*
 * 包装类的使用面试题:
 */
public class InterviewTest {
    @Test
    public void test1() {
        Object o1 = true ? new Integer(1) : new Double(2.0); //  编译时要求":"两边类型一致,Integer提升为Double
        System.out.println(o1); // 1.0
    }
    @Test
    public void test2() {
        Object o2; 
        if (true) 
            o2 = new Integer(1); 
        else 
            o2 = new Double(2.0);
        System.out.println(o2); // 1
    }
    @Test
    public void test3() { 
        Integer i = new Integer(1); 
        Integer j = new Integer(1); 
        System.out.println(i == j); // false
        
        Integer m = 1; 
        Integer n = 1; 
        System.out.println(m == n); // true
        
        Integer x = 128; // 相当于new了一个Integer对象
        Integer y = 128; 
        System.out.println(x == y); // false
        /*
         * Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],保存了从-128-127范围的整数,如果我们使用
         * 自动装箱的方式,给Integer赋值的范围在-128-127范围内,可以直接使用数组中的元素,不用再去new了,目的:提高效率
         */
    }

}
InterviewTest.java

8 - 关于包装类的使用练习

/*
利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出 最高分,并输出学生成绩等级。

  1 提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的 长度。而向量类java.util.Vector可以根据需要动态伸缩。

  2 创建Vector对象:Vector v=new Vector();

  3 给向量添加元素:v.addElement(Object obj); //obj必须是对象

  4 取出向量中的元素:Object obj=v.elementAt(0); 注意第一个元素的下标是0,返回值是Object类型的。

  5 计算向量的长度:v.size();

  6 若与最高分相差10分内:A等;20分内:B等; 30分内:C等;其它:D等
*/

package com.company;
import java.util.Vector;
import java.util.Scanner;
/*
利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出 最高分,并输出学生成绩等级。
    提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的 长度。而向量类java.util.Vector可以根据需要动态伸缩。
    创建Vector对象:Vector v=new Vector();
    给向量添加元素:v.addElement(Object obj);   //obj必须是对象
    取出向量中的元素:Object  obj=v.elementAt(0); 注意第一个元素的下标是0,返回值是Object类型的。
    计算向量的长度:v.size();
    若与最高分相差10分内:A等;20分内:B等; 30分内:C等;其它:D等
 */
public class ExerTest {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in); // 实例化Scanner,获取从键盘输入的学生成绩
        Vector v = new Vector(); // 实例化Vector,相当于原来的数组

        // 通过循环的方式,给Vector添加元素
        int maxScore = 0;
        for(;;){
            System.out.print("请输入学生成绩(输入负数结束):");
            int score = scan.nextInt();
            if(score < 0){
                break;
            }
            if(score > 100){
                System.out.println("输入成绩非法,请重新输入!");
                continue;
            }
            Integer inter = new Integer(score); // jdk 5.0之前,5.0之后直接扔进去即可
            v.addElement(inter);
            // 获取学生成绩最大值
            if(score > maxScore){
                maxScore = score;
            }
        }
        System.out.println("学生成绩最高分是"+maxScore);
        String level;
        for(int i = 0;i < v.size();i++){ // v.size() 表示向量的长度
            Object obj = v.elementAt(i);
            // jdk 5.0之前
            Integer inte = (Integer)obj;
            if(maxScore - inte.intValue() <= 10){
                level = "A";
            }else if(maxScore - inte.intValue() <= 20){
                level = "B";
            }else if(maxScore - inte.intValue() <= 30){
                level = "C";
            }else{
                level = "D";
            }
            System.out.println("student "+i+" score is "+inte.intValue()+" grade is "+level);
        }
    }
}
ExerTest

 

posted @ 2020-06-03 13:49  赖正华  阅读(717)  评论(0编辑  收藏  举报