Educoder- 《JAVA从小白到大牛》(第二章)2-6 Java面向对象 - 常用类

本文主要介绍了Java中的Object类,包括Object类的方法如hashCode()和toString(),以及对象克隆的概念。此外,还涉及到了Random类的使用,如生成随机数的方法,并通过实例展示了如何创建和使用Random对象。文章最后提到了Date类和SimpleDateFormat类以及Math类的使用,为读者提供了Java基础类库的重要知识。

提示:本文章为个人学习记录,仅供参考学习,禁止转载,支持交流与讨论。

第1关:Object类

相关知识

为了完成本关任务,你需要掌握:

1.什么是Object类;

2.Object类的方法;

3.Java对象克隆。

什么是Object类

Java中有一个比较特殊的类,就是 Object类,它是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类就默认继承Object类。因此,Object 类是 Java 类层中的最高层类,是所有类的超类。换句话说,Java 中任何一个类都是它的子类。由于所有的类都是由Object类衍生出来的,所以 Object类中的方法适用于所有类。

public class Person //当没有指定父类时,会默认 Object 类为其父类
{
    ...
}
//上面的程序等价于:

public class Person extends Object
{
    ...
}

如果想引用你不知道的类型的对象,使用Object类是没有错的。请注意,父类引用变量可以引用子类对象,称为向上转换。下面举一个例子,有一个getObject()方法返回一个对象,但它可以是任何类型,如:Employee,Student等这样的类,我们可以使用Object类引用来引用该对象。 例如:

Object obj=getObject();//we don't know what object will be returned from this method

Object类为所有对象提供了一些常见的行为,如对象可以进行比较,对象可以克隆,对象可以通知等。
在这里插入图片描述
Object类的常用方法有:toString()equals()方法。

1.关于toString()方法

在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串);

可以通过重写toString()方法表示出对象的属性。

此方法是在打印对象时被调用的,下面有两个范例,一个是没复写toString()方法,另一个是复写toString()方法,读者可比较两者的区别。

package educoder;
public class TestToStringDemo1 {
    public static void main(String[] args) {
        Person p = new Person();
        System.out.println(p);
    }
}
class Person extends Object {
    String name = "张三";
    int age = 18;
}

输出结果:
educoder.Person@7852e922
从上面的程序中可以发现,在打印对象p的时候实际上打印出的是一些无序的字符串,这样的字符串很少有人能看懂什么意思,之后可以再观察下面的范例,下面的范例复写了Object类中的 toString()方法。

package educoder;
public class TestToStringDemo2 {
    public static void main(String[] args) {
        Person p = new Person();
        System.out.println(p);
    }
}
class Person extends Object {
    String name = "张三";
    int age = 18;
    // 复写Object类中的toString()方法
    public String toString() {
        return "我是:" + this.name + ",今年:" + this.age + "岁";
    }
}

输出结果:
我是:张三,今年:18岁

2.关于equals()方法

比较的是对象的引用是否指向同一块内存地址,一般情况下,比较两个对象时是比较它的值是否一致,那如何解决呢?思路也比较简单,重写equals()方法。

在不重写的情况下,我们先看下程序执行情况,创建两个相同类型的对象,并判断对象是否相等。

ackage educoder;
public class test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "jack";
        Dog dog1 = new Dog();
        dog1.name = "jack";
        System.out.println(dog);
        System.out.println(dog1);
        if (dog.equals(dog1)) {
            System.out.println("两个对象是相同的");
        } else {
            System.out.println("两个对象是不相同的");
        }
    }
}
class Animal {
}
class Dog extends Animal {
    int age = 20;
    String name = "rose";
    public String toString() {
        return "Dog [age=" + age + ", name=" + name + "]";
    }
    }

输出结果:
Dog [age=20, name=jack]
Dog [age=20, name=jack]

两个对象是不相同的

分析下 : 两个对象分别new了一次,开辟了两个不同内存空间,内存地址不同。object提供的equals()是用来比较的是对象的引用是否指向同一块内存地址。很显然,内存地址不一样,所以是不相等的,跟属性值是否一样完全没有任何关系。

equals()==的区别:

在Java中,任何类型的数据都可以用“==”进行比较是不是相等,一般用于基本数据类型的比较,比较器存储的值是否相等。但是如果用于引用类型的比较,则是比较所指向对象的地址是否相等,在这点上,跟object类提供的equals()方法的作用是一致的。
对于equals()方法
首先,不能用于基本数据类型的变量之间的比较相等;

如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

诸如String、Date等类都对equals方法进行了重写,比较的是所指向的对象的内容

Java对象克隆

对象克隆是一种创建对象的精确副本的方法。 Object类的clone()方法用于克隆对象。java.lang.Cloneable接口必须由我们要创建其对象克隆的类实现。如果我们不实现Cloneable接口,clone()方法将生成CloneNotSupportedException

clone()方法在Object类中定义。clone()方法的语法如下:

少处理任务。
clone()方法示例(对象克隆)

package educoder;
public class Student implements Cloneable {
    int rollno;
    String name;
    Student(int rollno, String name) {
        this.rollno = rollno;
        this.name = name;
    }
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public static void main(String args[]) {
        try {
            Student s1 = new Student(101, "amit");
            Student s2 = (Student) s1.clone();
            System.out.println(s1.rollno + " " + s1.name);
            System.out.println(s2.rollno + " " + s2.name);
        } catch (CloneNotSupportedException c) {
        }
    }
}

}
输出结果:
101 amit
101 amit

从上面的例子可以看出,两个引用变量都有相同的值。 因此,clone()将对象的值复制到另一个对象。 因此,在实际应用中我们不需要编写显式代码将对象的值复制到另一个对象。如果通过new关键字创建另一个对象并将另一个对象的值赋给这个对象,则需要对该对象进行大量处理。 所以为了节省额外的处理任务,我们使用clone()方法。

编程要求

请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

Demo类Person类已经写好,在测试类中创建Demo类对象d1,传入输入值num1d1调用toString方法并打印输出该值;

创建Demo类对象d2,同样传入输入值num1,打印判断d1d2是否相等(实际是比较地址);

创建Person类对象p,传入输入值num2,打印判断d1p是否相等(实际是比较地址);

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

测试输入:
100
100

预期输出:
Demo:100
true
false

参考答案

package case1;

import java.util.Scanner;

public class ObjectTest {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num1 = sc.nextInt();
		int num2 = sc.nextInt();
		// 在测试类中创建Demo类对象d1,传入输入值num1, d1调用toString方法并打印输出该值
		// 创建Demo类对象d2,同样传入输入值num1,打印判断d1和d2是否相等(实际是比较地址)
		/********* Begin *********/
        Demo d1 =new Demo(num1);
        System.out.println(d1.toString());
        Demo d2 = new Demo(num1);
        System.out.println(d1.equals(d2));
       
		/********* End *********/
		// 创建Person类对象p,传入输入值num2,打印判断d1和p是否相等(实际是比较地址)
		/********* Begin *********/
        Person p = new Person(num2);
        System.out.println(d1.equals(p));
		/********* End *********/
	}
}

class Demo {
	private int num;

	public Demo(int num) {
		this.num = num;
	}

	public boolean equals(Object obj) // Object obj = new Demo()
	{
		if (!(obj instanceof Demo)) // 判断obj是否和Demo是同类
			return false;
		Demo d = (Demo) obj; // 将父类的引用(Object)向下转换为子类(Demo)
		return this.num == d.num;
	}

	public String toString() {
		return "Demo:" + num; // 返回对象的值(每一个对象都有自己的特定的字符串)
	}
}

class Person {
	private int num;

	public Person(int num) {
		this.num = num;
	}
}

第2关:JAVA基础类型包装类-练习

参考答案

package case2;

import java.util.Scanner;

public class WrapperTest {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int aa = sc.nextInt();
		String bb = sc.next();
		int c = sc.nextInt();
		String str11 = sc.next();
		String str22 = sc.next();
		// 包装类中“==”与equals的用法比较
		// 值得注意的是,包装类中的equals方法和String类一样,都是重写了Object类中的equals方法,因此比较的是内容而不是地址,
		// 而“==”比较的依然是引用变量的地址,只是当包装类型和与之相对应的基本类型进行“==”比较时会先做自动拆箱处理。
		/********* Begin *********/
        Integer a = new Integer(aa);
        Integer b = Integer.valueOf(bb);
        String str1 = new String(str11);
        String str2 = new String(str11);
        System.out.println(a==b);
        System.out.println(a==c);
        System.out.println(b==c);
        System.out.println(a.equals(b));
        System.out.println(str1==str2);
        System.out.println(str1.equals(str2));
		/********* End *********/
	}
}

第3关:String&StringBuilder&StringBuffer类-练习

参考答案

package case3;

import java.util.Scanner;

public class StringTest {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		// String substring(int start,int end)
		// 截取字符串,传入的两个参数分别为要截取边界的下标
		// 在java api 中,通常使用两个数字表示范围时,都是含头不含尾,即包含起始下标对应的内容,但不包含结束下标的处对应的内容
		// String toUpperCase() 将当前字符串中的英文部分转换为全大写
		/********* Begin *********/
        /**int i = str.length();
        int s = str.indexOf(".");
        int e = str.lastIndexOf(".");
        str = str.substring(s+1,e);
        if(str.indexOf(".")==-1){
        System.out.println(str);
        str = str.toUpperCase();
        System.out.println(str);
        }**/
        StringBuilder s = new StringBuilder(str);
        s=new StringBuilder(s.substring(s.indexOf(".")+1));
        s=new StringBuilder(s.substring(0,s.indexOf(".")));
        System.out.println(s);
        System.out.println(s.toString().toUpperCase());
		/********* End *********/
	}
}

第4关:Random类

相关知识

为了完成本关任务,你需要掌握:

1.Random类;

2.Random对象的生成;

3.Random类中的常用方法。

Random类

Random类位于java.util包下,Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。

相同种子数Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。

Random对象的生成

Random类包含两个构造方法,下面依次进行介绍:

public Random()

该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。

public Random(long seed)

该构造方法可以通过制定一个种子数进行创建。
示例代码:

Random r = new Random();
Random r1 = new Random(10);

再次强调:种子数只是随机算法的起源数字,和生成的随机数字的区间无关。
验证:相同种子数的Random对象,相同次数生成的随机数字是完全相同的。

package educoder;
import java.util.Random;
public class RandomTest {
    public void random() {
        int i = 0;
        int j = 0;
        Random random = new Random(1);
        Random random1 = new Random(1);
        i = random.nextInt();
        j = random1.nextInt();
        System.out.println("i:" + i + "\nj:" + j);
    }
    public static void main(String[] args) {
        RandomTest tt = new RandomTest();
        tt.random();
    }
}

输出结果:
第一次:
i:-1155869325
j:-1155869325

修改一下起源数字,让其等于100。

Random random = new Random(100);
Random random1 = new Random(100);

输出结果:
i:-1193959466
j:-1193959466

Random类中的常用方法

Random类中的方法比较简单,每个方法的功能也很容易理解。需要说明的是,Random类中各方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率是均等的。下面对这些方法做一下基本的介绍:

package educoder;
import java.util.Random;
public class RandomTest {
    public static void main(String[] args) {
        Random random = new Random();
        System.out.println("nextInt():" + random.nextInt()); // 随机生成一个整数,这个整数的范围就是int类型的范围-2^31~2^31-1
        System.out.println("nextLong():" + random.nextLong()); // 随机生成long类型范围的整数
        System.out.println("nextFloat():" + random.nextFloat()); // 随机生成[0, 1.0)区间的小数
        System.out.println("nextDouble():" + random.nextDouble()); // 随机生成[0, 1.0)区间的小数
        System.out.println("nextBoolean():"+random.nextBoolean());//随机生成一个boolean值,生成true和false的值几率相等,也就是都是50%的几率
        System.out.println("nextGaussian():"+random.nextGaussian());//随机生成呈高斯(“正态”)分布的 double 值,其平均值是 0.0,标准差是 1.0
        byte[] byteArr = new byte[5];
        random.nextBytes(byteArr); // 随机生成byte,并存放在定义的数组中,生成的个数等于定义的数组的个数
        System.out.print("nextBytes():");
        for (int i = 0; i < byteArr.length; i++) {
                System.out.print(byteArr[i]+"\t");
        }
        System.out.println();
        /**
         * random.nextInt(n) 
         * 随机生成一个正整数,整数范围[0,n),包含0而不包含n
         * 如果想生成其他范围的数据,可以在此基础上进行加减
         *
         * 例如: 
         * 1. 想生成范围在[0,n]的整数 
         *         random.nextInt(n+1) 
         * 2. 想生成范围在[m,n]的整数, n > m
         *         random.nextInt(n-m+1) + m 
         *         random.nextInt() % (n-m) + m 
         * 3. 想生成范围在(m,n)的整数
         *         random.nextInt(n-m+1) + m -1 
         *         random.nextInt() % (n-m) + m - 1 
         * ......主要是依靠简单的加减法
         */
        System.out.println("nextInt(10):" + random.nextInt(10)); // 随机生成一个整数,整数范围[0,10)
        for (int i = 0; i < 5; i++) {
            System.out.println("我生成了一个[3,15)区间的数,它是:" + (random.nextInt(12) + 3));
        }
        /**
         * random.nextDouble() 
         * 例如:
         * 1.生成[0,1.0)区间的小数
         *         double d1 = random.nextDouble();//直接使用nextDouble方法获得。
         * 2.生成[0,5.0)区间的小数
         *           double d2 = random.nextDouble() * 5;//因为扩大5倍即是要求的区间。同理,生成[0,d)区间的随机小数,d为任意正的小数,则只需要将nextDouble方法的返回值乘以d即可。
         * 3.生成[1,2.5)区间的小数
         *         double d3 = r.nextDouble() * 1.5 + 1;//生成[1,2.5)区间的随机小数,则只需要首先生成[0,1.5)区间的随机数字,然后将生成的随机数区间加1即可。
         * ......同理,生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。
         * 
         */
        }
}

输出结果:
nextInt():1842341002
nextLong():4006643082448092921
nextFloat():0.88948154
nextDouble():0.5635189241159165
nextBoolean():false
nextGaussian():1.3191426544832998
nextBytes():36 100 94 14 -98
nextInt(10):1
我生成了一个[3,15)区间的数,它是:5
我生成了一个[3,15)区间的数,它是:10
我生成了一个[3,15)区间的数,它是:10
我生成了一个[3,15)区间的数,它是:11
我生成了一个[3,15)区间的数,它是:6

编程要求

(“编程要求”部分介绍本关任务的具体要求,如实现步骤,规则等,最好能给出效果图)
请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

设计一个密码的自动生成器:密码由大写字母/小写字母/数字组成,生成六位随机密码。

分别以1、2、3作为种子数创建Random对象,生成六位随机密码进行测试。

具体输出要求请看测试说明。

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

测试输入:
1
预期输出:
NAvZuG

参考答案

package case4;

//密码的自动生成器:密码由大写字母/小写字母/数字组成,生成六位随机密码
import java.util.Random;
import java.util.Scanner;

public class RandomTest {
	public static void main(String[] args) {
		// 定义一个字符型数组
		char[] pardStore = new char[62];
		// 把所有的大写字母放进去 把所有的小写字母放进去 把0到9放进去
		/********* Begin *********/

        /**int i=0 
        for(;i<62;i++){
            char pardStore[i]=A+i;
        }**/   //按ASCII码进行添加 但不知添加方式
        for(int i=0;i<26;i++){
            pardStore[i]=(char)('A'+i);
        }
        for(int i=26;i<52;i++){
            pardStore[i]=(char)('a'+(i-26));
        }
        for(int i=52;i<62;i++){
            pardStore[i]=(char)('0'+(i-52));
        }
		/********* End *********/
		// 分别以1、2、3作为种子数 生成6位随机密码
		Scanner sc = new Scanner(System.in);
		int seed = sc.nextInt();
		/********* Begin *********/
       /** Random random1 = new Random(seed);
        for() **/  //没理解题意,不知道如何取随机数
        Random r = new Random(seed);
        for(int i=0;i<6;i++){
            int n = r.nextInt(62);
            System.out.print(pardStore[n]);
        } 
		/********* End *********/
	}
}

第5关:Date类和SimpleDateFormat类的用法

详细知识点请参考:
https://www.runoob.com/java/java-date-time.html

参考答案

package case5;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class DateTest {
    public static void main(String[] args) throws ParseException {
        // 键盘录入你的出生年月日 格式为yyyy-MM-dd
        // 把该字符串转换为一个日期
        // 通过该日期得到一个毫秒值
        // 获取2020年10月1日的毫秒值
        // 两者想减得到一个毫秒值
        // 把该毫秒值转换为天 打印输出
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        /********* Begin *********/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = sdf.parse(line);
        long myTime = d1.getTime();
        Date d2 = sdf.parse("2020-10-01");
        long endTime = d2.getTime();
        long time = endTime - myTime;
        long day = time / 1000 / 60 / 60 / 24;
        System.out.println("你的出生日期距离2020年10月1日:" + day + "天");
        /********* End *********/
    }
}

第6关:Math类

任务描述

本关任务:掌握Math类和Math类中的部分方法。

相关知识

为了完成本关任务,你需要掌握:
1.Math类;
2.Math类中常用方法。

Math类

Math类是一个工具类,它的构造器被定义成private的,因此无法创造Math类的对象。Math类中所有的方法都是类方法,可以直接通过类名来调用他们。
Math类包含完成基本数学函数所需的方法。这些方法基本可以分为三类:三角函数方法、指数函数方法和服务方法。在Math类中定义了PIE两个double型常量,PI就是π的值,而Ee指数底的值,分别是:3.1415926535897932.718281828459045

Math类中常用方法

三角函数方法;
Math类包含下面的三角函数方法:

· Math.toDegrees

这个方法是将-π/2π/2之间的弧度值转化为度,例如:Math.toDegrees(Math.PI/2)结果为90.0

· Math.toRadians
这个方法是将度转化为-π/2π/2之间的弧度值,例如:Math.toRadians(30)结果为π/6

Math.sinMath.cosMath.tan这三个方法是三角函数中的正弦、余弦和正切,反之Math.asinMath.acosMath.atan是他们的反函数。

· 指数函数方法;
Math类中有五个与指数函数相关的方法Math.exp(a)方法主要是获得以 e 为底a为指数的数值;Math.log()Math.log10()对数函数Math.pow(a,b)是以a为底b为指数的值;Math.sqrt()是开根号。

· 取整方法;
Math类里包含五个取整方法:Math.ceil()方法是往大里取值;Math.floor()方法是往小里取值;Math.rint()方法返回与参数最接近的整数,返回类型为double,注意.5的时候会取偶数;Math.round()方法分两种:int型和long型,Math.round(a)就是Math.floor(a+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。

min、max和abs方法
取最大值和最小值以及绝对值。

· random方法。
生成随机数取值范围是0.0到1.0的double型数值。也可以用简单的表达式生成任意范围的随机数,例如:
(int)(Math.random()*10)返回0到9之间的一个随机整数。

参考答案

package case6;

import java.util.Scanner;
import java.lang.Math;

public class MathTest {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int a1 = sc.nextInt();
		int a2 = sc.nextInt();
		int a3 = sc.nextInt();
		int a4 = sc.nextInt();
		double a5 = sc.nextDouble();
		double a6 = sc.nextDouble();
		double a7 = sc.nextDouble();
		double a8 = sc.nextDouble();
		double a9 = sc.nextDouble();
		double a10 = sc.nextDouble();
		double a11 = sc.nextDouble();
		/********* Begin *********/
        System.out.println(Math.sqrt(a1));
        System.out.println(Math.cbrt(a2));
        System.out.println(Math.pow(a3,a4));
        System.out.println(Math.max(a5,a6));
        System.out.println(Math.min(a5,a6)); //int || doble
        System.out.println(Math.abs(a7));//double
        System.out.println(Math.ceil(a8));  //double >0.5==1
        System.out.println(Math.floor(a9)); //double >0.5==1
        System.out.println(Math.rint(a10)); //数+1=单;0.5 ==0  双==1;double
        System.out.println(Math.round(a11));//double //>=0.5 ==1
		/********* End *********/
	}
}

END

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值