5-面向对象编程中

面向对象编程[中]

image-20210316193640125

7、object类的使用

8、包装类的使用

1、继承性

面向对象的特征之二:继承性 why?

一、继承性的好处:

① 减少了代码的冗余,提高了代码的复用性

② 便于功能的扩展

③ 为之后多态性的使用,提供了前提

二、继承性的格式:

class A extends B{}

A:子类、派生类、subclass

B:父类、超类、基类、superclass

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DLJ5dpu8-1616400648644)(E:\project\mp\java\day6-10\pic\image-20210316194955328.png)]

2.1体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。

特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。

只有因为封装性的影响,使得子类不能直接调用父类的结构而已。

2.2 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。

子类和父类的关系,不同于子集和集合的关系。

extends:延展、扩展

三、Java中关于继承性的规定:

1.一个类可以被多个子类继承。

2.Java中类的单继承性:一个类只能有一个父类

3.子父类是相对的概念。

4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类

5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法

四、

  1. 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类

  2. 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类

  3. 意味着,所有的java类具有java.lang.Object类声明的功能。

package com.atguigu.java;

public class ExtendsTest {
	public static void main(String[] args) {
		
		Person p1 = new Person();
//		p1.age = 1;
		p1.eat();
		System.out.println("*****************");
		
		Student s1 = new Student();
		s1.eat();
//		s1.sleep();
		s1.name = "Tom";
		s1.setAge(10);
		System.out.println(s1.getAge());
		
		s1.breath();
		
		
		Creature c = new Creature();
		System.out.println(c.toString());
	}
}

父类

package com.atguigu.java;

public class Person extends Creature{
	
	String name;
	private int age;
	
	public Person(){
		
	}
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	public void eat(){
		System.out.println("吃饭");
		sleep();
	}
	
	private void sleep(){
		System.out.println("睡觉");
	}

	public int getAge() {
		return age;
	}

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

子类

package com.atguigu.java;

public class Student extends Person{
	
//	String name;
//	int age;
	String major;
	
	public Student(){
		
	}
	public Student(String name,int age,String major){
		this.name = name;
//		this.age = age;
		setAge(age);
		this.major = major;
	}
//	public void eat(){
//		System.out.println("吃饭");
//	}
//	
//	public void sleep(){
//		System.out.println("睡觉");
//	}
	
	public void study(){
		System.out.println("学习");
	}
	
	public void show(){
		System.out.println("name:" + name + ",age:" + getAge());
	}
	
}

create

package com.atguigu.java;

public class Creature {
	
	public void breath(){
		System.out.println("呼吸");
	}
	
}

练习1

image-20210316195825526
package com.atguigu.exer;
/*
 * 定义一个ManKind类,包括
成员变量int sex和int salary;
方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。

 */
public class ManKind {
	
	private int sex;//性别
	private int salary;//薪资
	
	public ManKind() {
	}
	

	public ManKind(int sex, int salary) {
		this.sex = sex;
		this.salary = salary;
	}


	public void manOrWoman(){
		if(sex == 1){
			System.out.println("man");
		}else if(sex == 0){
			System.out.println("woman");
		}
	}
	
	public void employeed(){
//		if(salary == 0){
//			System.out.println("no job");
//		}else{
//			System.out.println("job");
//		}
		//或
		String jobInfo = (salary == 0)? "no job" : "job";
		System.out.println(jobInfo);
	}

	public int getSex() {
		return sex;
	}

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

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}
	
	
}

类Kids

package com.atguigu.exer;
/*
 * 定义类Kids继承ManKind,并包括
成员变量int yearsOld;
方法printAge()打印yearsOld的值。

 */
public class Kids extends ManKind{
	private int yearsOld;
	
	public Kids() {
	}

	public Kids(int yearsOld) {
		this.yearsOld = yearsOld;
	}

	public void printAge(){
		System.out.println("I am " + yearsOld + " years old.");
		
	}

	public int getYearsOld() {
		return yearsOld;
	}

	public void setYearsOld(int yearsOld) {
		this.yearsOld = yearsOld;
	}
	/*
	 * 修改练习1.2中定义的类Kids,在Kids中重新定义employeed()方法,
	 * 覆盖父类ManKind中定义的employeed()方法,
	 * 输出“Kids should study and no job.”
	 */
	
	public void employeed() {
		System.out.println("Kids should study and no job.");
	}
}

类Kids Test

package com.atguigu.exer;
/*
 * 定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。

 */
public class KidsTest {
	public static void main(String[] args) {
		
		Kids someKid = new Kids(12);
		
		someKid.printAge();
		
		someKid.setSalary(0);
		someKid.setSex(1);
		
		someKid.employeed();
		someKid.manOrWoman();
		
		
	}
}

练习2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OYU7beL3-1616400648646)(E:\project\mp\java\day6-10\pic\image-20210316200548360.png)]

Circle

package com.atguigu.exer1;

public class Circle {
	
	private double radius;//半径
	
	public Circle(){
		radius = 1.0;
	}
//	
	public Circle(double radius){
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	//返回圆的面积
	public double findArea(){
		return Math.PI * radius * radius;
	}
	
}

Cylinder

package com.atguigu.exer1;

public class Cylinder extends Circle{
	
	private double length;//高
	
	public Cylinder(){
		length = 1.0;
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		this.length = length;
	}
	
	//返回圆柱的体积
	public double findVolume(){
//		return Math.PI * getRadius() * getRadius() * getLength();
		return super.findArea() * getLength();
	}
	
	@Override
	public double findArea() {//返回圆柱的表面积
		return Math.PI * getRadius() * getRadius() * 2 + 
				2 * Math.PI * getRadius() * getLength();
	}

}

Cylinder

package com.atguigu.exer1;

public class CylinderTest {
	public static void main(String[] args) {
		
		Cylinder cy = new Cylinder();
		
		cy.setRadius(2.1);
		cy.setLength(3.4);
		double volume = cy.findVolume();
		System.out.println("圆柱的体积为:" + volume);
		
		//没有重写findArea()时:
//		double area = cy.findArea();
//		System.out.println("底面圆的面积:" + area);
		//重写findArea()以后:
		double area = cy.findArea();
		System.out.println("圆柱的表面积:" + area);
		
		System.out.println("******************");
		Cylinder cy1 = new Cylinder();
		double volume1 = cy1.findVolume();
		System.out.println("圆柱的体积为:" + volume1);
	}
}

2、方法的重写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bFFjHQIm-1616400648647)(E:\project\mp\java\day6-10\pic\image-20210316201116325.png)]

方法的重写(override / overwrite)

1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作

2.应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。

3.重写的规定:

方法的声明: 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{

//方法体

}

约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法

① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同

② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符

特殊情况:子类不能重写父类中声明为private权限的方法

③ 返回值类型:

父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void

父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类

父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)

④ 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)


子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。

面试题:区分方法的重载与重写

父类Person

package com.atguigu.java1;

public class Person {
	
	String name;
	int age;
	
	public Person(){
		
	}
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	 void eat(){
		System.out.println("吃饭");
	}
	public void walk(int distance){
		System.out.println("走路,走的距离是:" + distance + "公里");
		show();
		eat();
	}
	
	private void show(){
		System.out.println("我是一个人");
	}
	
	public Object info(){
		return null;
	}
	
	public double info1(){
		return 1.0;
	}

}

子类:Student

package com.atguigu.java1;

public class Student extends Person{

	String major;
	
	public Student(){
		
	}
	public Student(String major){
		this.major = major;
	}
	
	public void study(){
		System.out.println("学习。专业是:" + major);
	}
	
	//对父类中的eat()进行了重写
	public void eat(){
		System.out.println("学生应该多吃有营养的食物");
	}
	
	public void show(){
		System.out.println("我是一个学生");
	}
	
	public String info(){
		return null;
	}
	
//	public int info1(){
//		return 1;
//	}
	
//	public void walk(int distance){
//		System.out.println("重写的方法");
//	}
	
	
	public void walk(int distance) {
		System.out.println("重写的方法");
	}

}

测试:Person Test

package com.atguigu.java1;

public class PersonTest {
	
	public static void main(String[] args) {
		
		Student s = new Student("计算机科学与技术");
		s.eat();
		s.walk(10);
		
		System.out.println("**************");
		
		s.study();
		
		Person p1 = new Person();
		p1.eat();
		
	}
}

3、四种访问权限修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g7OyVmnO-1616400648650)(E:\project\mp\java\day6-10\pic\image-20210316201330737.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2usOGyKk-1616400648651)(E:\project\mp\java\day6-10\pic\image-20210316201720211.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EfxHfSzz-1616400648652)(E:\project\mp\java\day6-10\pic\image-20210316201746684.png)]

image-20210316201814142

例子

package com.atguigu.java2;
/*
 * 体会4种不同的权限修饰
 * 
 * 
 */
public class Order {
	
	private int orderPrivate;
	int orderDefault;
	protected int orderProtected;
	public int orderPublic;
	
	private void methodPrivate(){
		orderPrivate = 1;
		orderDefault = 2;
		orderProtected = 3;
		orderPublic = 4;
	}
	void methodDefault(){
		orderPrivate = 1;
		orderDefault = 2;
		orderProtected = 3;
		orderPublic = 4;
	}
	protected void methodProtected(){
		orderPrivate = 1;
		orderDefault = 2;
		orderProtected = 3;
		orderPublic = 4;
	}
	
	public void methodPublic(){
		orderPrivate = 1;
		orderDefault = 2;
		orderProtected = 3;
		orderPublic = 4;
	}
}

test

package com.atguigu.java2;

public class OrderTest {
	public static void main(String[] args) {
		Order order = new Order();
		
		order.orderDefault = 1;
		order.orderProtected = 2;
		order.orderPublic = 3;
		
		order.methodDefault();
		order.methodProtected();
		order.methodPublic();
		
		//同一个包中的其他类,不可以调用Order类中私有的属性、方法
//		order.orderPrivate = 4;
//		order.methodPrivate();
	}
}

4、关键字——super

super关键字的使用

1.super理解为:父类的

2.super可以用来调用:属性、方法、构造器

3.super的使用:调用属性和方法

3.1 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用

父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."

3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的

使用"super.属性"的方式,表明调用的是父类中声明的属性。

3.3 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的

使用"super.方法"的方式,表明调用的是父类中被重写的方法。

4.super调用构造器

4.1 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器

4.2 "super(形参列表)"的使用,必须声明在子类构造器的首行!

4.3 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现

4.4 在构造器的首行,没有显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()

4.5 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YIyfHDIL-1616400648653)(E:\project\mp\java\day6-10\pic\image-20210316213852181.png)]

person

package com.atguigu.java3;

public class Person {
	String name;
	int age;
	int id = 1001;//身份证号
	
	public Person(){
		System.out.println("我无处不在!");
	}
	
	public Person(String name){
		this.name = name;
	}
	
	public Person(String name,int age){
		this(name);
		this.age = age;
	}
	
	public void eat(){
		System.out.println("人:吃饭");
	}
	public void walk(){
		System.out.println("人:走路");
	}
}

Student

package com.atguigu.java3;

public class Student extends Person{
	
	String major;
	int id = 1002;//学号
	
	public Student(){
		super();
	}
	public Student(String major){
		super();
		this.major = major;
	}
	
	public Student(String name,int age,String major){
//		this.name = name;
//		this.age = age;
		super(name,age);
		this.major = major;
	}
	
	@Override
	public void eat() {
		System.out.println("学生:多吃有营养的食物");
	}
	
	public void study(){
		System.out.println("学生:学习知识");
		this.eat();
		super.eat();
		walk();
	}
	
	public void show(){
		System.out.println("name = " + name + ", age = " + age);
		System.out.println("id = " + this.id);
		System.out.println("id = " + super.id);
	}
}

SuperTest

package com.atguigu.java3;

public class SuperTest {
	public static void main(String[] args) {
		
		Student s = new Student();
		s.show();
		
		System.out.println();
		
		s.study();
		
		Student s1 = new Student("Tom", 21, "IT");
		s1.show();
		
		System.out.println("************");
		Student s2 = new Student();
		
	}
}
/*
我无处不在!
name = null, age = 0
id = 1002
id = 1001

学生:学习知识
学生:多吃有营养的食物
人:吃饭
人:走路
name = Tom, age = 21
id = 1002
id = 1001
************
我无处不在!

*/

练习

Account

package com.atguigu.exer2;

public class Account {
	private int id;//账号
	private double balance;//余额
	private double annualInterestRate;//年利率
	
	public Account(int id, double balance, double annualInterestRate) {
		super();
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}

	public double getAnnualInterestRate() {
		return annualInterestRate;
	}

	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	//返回月利率
	public double getMonthlyInterest(){	
		return annualInterestRate / 12;
	}
	//取钱
	public void withdraw (double amount){
		if(balance >= amount){
			balance -= amount;
			return;
		}
		System.out.println("余额不足");
	}
	//存钱
	public void deposit (double amount){
		if(amount > 0){
			balance += amount;
		}
	}


}

AccountTest

package com.atguigu.exer2;
/*
 * 写一个用户程序测试Account类。在用户程序中,
 * 创建一个账号为1122、余额为20000、年利率4.5%的Account对象。
 * 使用withdraw方法提款30000元,并打印余额。
 * 再使用withdraw方法提款2500元,
 * 使用deposit方法存款3000元,然后打印余额和月利率。

 * 
 */
public class AccountTest {
	public static void main(String[] args) {
		
		Account acct = new Account(1122, 20000, 0.045);
		
		acct.withdraw(30000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		acct.withdraw(2500);
		System.out.println("您的账户余额为:" + acct.getBalance());
		acct.deposit(3000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		
		System.out.println("月利率为:" + (acct.getMonthlyInterest() * 100) +"%");
		
		
		
		
	}
}
/*
余额不足
您的账户余额为:20000.0
您的账户余额为:17500.0
您的账户余额为:20500.0
月利率为:0.375%

*/

CheckAccount

package com.atguigu.exer2;
/*
 * 创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。
 * 在CheckAccount类中重写withdraw方法,其算法如下:
		如果(取款金额<账户余额),
		可直接取款
		如果(取款金额>账户余额),
		计算需要透支的额度
		判断可透支额overdraft是否足够支付本次透支需要,如果可以
			将账户余额修改为0,冲减可透支金额
		如果不可以
			提示用户超过可透支额的限额

 * 
 * 
 */
public class CheckAccount extends Account{
	
	private double overdraft;//可透支限额
	
	public CheckAccount(int id, double balance, double annualInterestRate,double overdraft){
		super(id, balance, annualInterestRate);
		this.overdraft = overdraft;
		
	}
	
	
	public double getOverdraft() {
		return overdraft;
	}


	public void setOverdraft(double overdraft) {
		this.overdraft = overdraft;
	}


	@Override
	public void withdraw(double amount) {
		if(getBalance() >= amount){//余额就足够消费
//			getBalance() -= amount;
			//方式一:
//			setBalance(getBalance() - amount); 
			//方式二:  父类取款
			super.withdraw(amount);
		}else if(overdraft >= amount - getBalance()){//透支额度+余额足够消费
			
			overdraft -= (amount - getBalance());
			
//			setBalance(0);
			//或
			super.withdraw(getBalance());
			
		}else{
			System.out.println("超过可透支限额!");
		}
	}

}

CheckAccountTest

package com.atguigu.exer2;
/*
 * 写一个用户程序测试CheckAccount类。
 * 在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。
	使用withdraw方法提款5000元,并打印账户余额和可透支额。
	再使用withdraw方法提款18000元,并打印账户余额和可透支额。
	再使用withdraw方法提款3000元,并打印账户余额和可透支额。

 * 
 */
public class CheckAccountTest {
	public static void main(String[] args) {
		
		CheckAccount acct = new CheckAccount(1122, 20000, 0.045, 5000);
		
		acct.withdraw(5000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:" + acct.getOverdraft());
		acct.withdraw(18000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:" + acct.getOverdraft());
		acct.withdraw(3000);
		System.out.println("您的账户余额为:" + acct.getBalance());
		System.out.println("您的可透支额度为:" + acct.getOverdraft());
		
	}
}
/*
您的账户余额为:15000.0
您的可透支额度为:5000.0
您的账户余额为:0.0
您的可透支额度为:2000.0
超过可透支限额!
您的账户余额为:0.0
您的可透支额度为:2000.0
*/

5、子类对象实例化过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-umZBGe0e-1616400648653)(E:\project\mp\java\day6-10\pic\image-20210316215743385.png)]

子类对象实例化的全过程

1.从结果上来看:(继承性)

子类继承父类以后,就获取了父类中声明的属性或方法。

创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。

2.从过程上来看:

当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,…

直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有

父类中的结构,子类对象才可以考虑进行调用。

明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。

6、多态性

面向对象特征之三:多态性

1.理解多态性:可以理解为一个事物的多种形态。

2.何为多态性:

对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

3.多态的使用:虚拟方法调用

有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,

但在运行期,我们实际执行的是子类重写父类的方法。

总结:编译,看左边;运行,看右边。

4.多态性的使用前提: ① 类的继承关系 ② 方法的重写

5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

例子

Person

package com.atguigu.java4;

public class Person {
	String name;
	int age;
	
	int id = 1001;
	
	public void eat(){
		System.out.println("人:吃饭");
	}
	
	public void walk(){
		System.out.println("人:走路");
	}
	
}

Man

package com.atguigu.java4;

public class Man extends Person{
	
	boolean isSmoking;
	
	int id = 1002;
	
	public void earnMoney(){
		System.out.println("男人负责挣钱养家");
	}
	
	public void eat(){
		System.out.println("男人多吃肉,长肌肉");
	}
	
	public void walk(){
		System.out.println("男人霸气的走路");
	}

}

Woman

package com.atguigu.java4;

public class Woman extends Person{
	
	boolean isBeauty;
	
	public void goShopping(){
		System.out.println("女人喜欢购物");
	}
	
	public void eat(){
		System.out.println("女人少吃,为了减肥");
	}
	
	public void walk(){
		System.out.println("女人窈窕的走路");
	}
}

PersonTest

public class PersonTest {
	
	
	public static void main(String[] args) {
		
		Person p1 = new Person();
		p1.eat();
		
		Woman woman = new Woman();
		woman.eat();
		woman.age = 25;
//		man.earnMoney();
		
		//*************************************************
		System.out.println("*******************");
		//对象的多态性:父类的引用指向子类的对象
		Person p2 = new Man();
//		Person p3 = new Woman();
		//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
		p2.eat();
		p2.walk();
		
//		p2.earnMoney();
		
		System.out.println(p2.id);//person 里面的1001
		
	}
}
/*
人:吃饭
女人少吃,为了减肥
*******************
男人多吃肉,长肌肉
男人霸气的走路
1001
*/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0xqK1tT-1616400648655)(E:\project\mp\java\day6-10\pic\image-20210316221130245.png)]

instanceof 操作符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FWPldGcn-1616400648655)(E:\project\mp\java\day6-10\pic\image-20210316221720371.png)]

package com.atguigu.java4;

import java.sql.Connection;


//多态性的使用举例一:
public class AnimalTest {
	
	public static void main(String[] args) {
		
		AnimalTest test = new AnimalTest();
		test.func(new Dog());
		
		
		test.func(new Cat());
	}
	
	public void func(Animal animal){//Animal animal = new Dog();
		animal.eat();
		animal.shout();
		
		if(animal instanceof Dog){
			Dog d = (Dog)animal;
			d.watchDoor();
		}
	}
	
//	public void func(Dog dog){
//		dog.eat();
//		dog.shout();
//	}
//	public void func(Cat cat){
//		cat.eat();
//		cat.shout();
//	}
}


class Animal{
	public void eat(){
		System.out.println("动物:进食");
	}
	
	public void shout(){
		System.out.println("动物:叫");
	}
	
	
}

class Dog extends Animal{
	public void eat(){
		System.out.println("狗吃骨头");
	}
	
	public void shout(){
		System.out.println("汪!汪!汪!");
	}
	
	public void watchDoor(){
		System.out.println("看门");
	}
}
class Cat extends Animal{
	public void eat(){
		System.out.println("猫吃鱼");
	}
	
	public void shout(){
		System.out.println("喵!喵!喵!");
	}
}

//举例二:

class Order{
	
	public void method(Object obj){
		
	}
}

//举例三:
class Driver{
	
	public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
		//规范的步骤去操作数据
//		conn.method1();
//		conn.method2();
//		conn.method3();
		
	}
	
}

练习

package com.atguigu.java5;


import java.util.Random;

//面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal  {
 
	protected void eat() {
		System.out.println("animal eat food");
	}
}

class Cat  extends Animal  {
 
	protected void eat() {
		System.out.println("cat eat fish");
	}
}

class Dog  extends Animal  {
 
	public void eat() {
		System.out.println("Dog eat bone");

	}

}

class Sheep  extends Animal  {
 

	public void eat() {
		System.out.println("Sheep eat grass");

	}

 
}

public class InterviewTest {

	public static Animal  getInstance(int key) {
		switch (key) {
		case 0:
			return new Cat ();
		case 1:
			return new Dog ();
		default:
			return new Sheep ();
		}

	}

	public static void main(String[] args) {
		int key = new Random().nextInt(3);

		System.out.println(key);

		Animal  animal = getInstance(key);
		
		animal.eat();
		 
	}

}

对象类型转换(Casting)

image-20210316224928857 image-20210316225101990

复杂版

package com.atguigu.java;

import java.util.Date;

public class PersonTest {
	public static void main(String[] args) {
		
		Person p1 = new Person();
		p1.eat();
		
		Man man = new Man();
		man.eat();
		man.age = 25;
		man.earnMoney();
		
		//*************************************************
		System.out.println("*******************");
		//对象的多态性:父类的引用指向子类的对象
		Person p2 = new Man();
//		Person p3 = new Woman();
		//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
		p2.eat();
		p2.walk();
//		p2.earnMoney();
		System.out.println(p2.id);//1001
		
		System.out.println("****************************");
		//不能调用子类所特有的方法、属性:编译时,p2是Person类型。
		p2.name = "Tom";
//		p2.earnMoney();
//		p2.isSmoking = true;
		//有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致
		//编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
		
		//如何才能调用子类特有的属性和方法?
		//向下转型:使用强制类型转换符。
		Man m1 = (Man)p2;//p2从person 强制转为man
		m1.earnMoney();
		m1.isSmoking = true;
		
		//使用强转时,可能出现ClassCastException的异常。
//		Woman w1 = (Woman)p2;
//		w1.goShopping();
		
		/*
		 * instanceof关键字的使用
		 * 
		 * a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
		 * 
		 * 
		 *  使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
		 *  进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
		 *  
		 *  如果 a instanceof A返回true,则 a instanceof B也返回true.
		 *  其中,类B是类A的父类。
		 */
		if(p2 instanceof Woman){
			Woman w1 = (Woman)p2;
			w1.goShopping();
			System.out.println("******Woman******");
		}
		
		if(p2 instanceof Man){
			Man m2 = (Man)p2;
			m2.earnMoney();
			System.out.println("******Man******");
		}
		
		if(p2 instanceof Person){
			System.out.println("******Person******");
		}
		if(p2 instanceof Object){
			System.out.println("******Object******");
		}
		
//		if(p2 instanceof String){
//			
//		}
		
		//练习:
		//问题一:编译时通过,运行时不通过
		//举例一:
//		Person p3 = new Woman();
//		Man m3 = (Man)p3;
		//举例二:
//		Person p4 = new Person();
//		Man m4 = (Man)p4;

		
		//问题二:编译通过,运行时也通过
//		Object obj = new Woman();
//		Person p = (Person)obj;
		
		//问题三:编译不通过
//		Man m5 = new Woman();
		
//		String str = new Date();
		
//		Object o = new Date();
//		String str1 = (String)o;
		
		
		
	}
}

/*
人:吃饭
男人多吃肉,长肌肉
男人负责挣钱养家
*******************
男人多吃肉,长肌肉
男人霸气的走路
1001
****************************
男人负责挣钱养家
男人负责挣钱养家
******Man******
******Person******
******Object******

*/

练习

package com.atguigu.exer;
/*
 * 练习:
 * 1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,
 * 系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边
 * 
 * 2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,
 * 这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
 */
class Base {
	int count = 10;

	public void display() {
		System.out.println(this.count);
	}
}

class Sub extends Base {
	int count = 20;

	public void display() {
		System.out.println(this.count);
	}
}

public class FieldMethodTest {
	public static void main(String[] args) {
		Sub s = new Sub();
		System.out.println(s.count);//20
		s.display();//20
		
		Base b = s;//多态性  Base b=new Sub();  调用Base的属性,Sub的方法
		//==:对于引用数据类型来讲,比较的是两个引用数据类型变量的地址值是否相同
		System.out.println(b == s);//true
		System.out.println(b.count);//10
		b.display();//20
	}
}

package com.atguigu.exer;

/*
 * 建立InstanceTest 类,在类中定义方法method(Person e);
		在method中:
		(1)根据e的类型调用相应类的getInfo()方法。
		(2)根据e的类型执行:
		如果e为Person类的对象,输出:
		“a person”;
		如果e为Student类的对象,输出:
		“a student”
		“a person ” 
		如果e为Graduate类的对象,输出: 
		“a graduated student”
		“a student”
		“a person” 

 * 
 * 
 * 
 */
public class InstanceTest {
	
	public static void main(String[] args) {
		
		InstanceTest test = new InstanceTest();
		test.method(new Graduate());
	}
	
	
	public void method(Person e){
		
		//虚拟方法调用
		String info = e.getInfo();
		System.out.println(info);
		
		//方式一
//		if(e instanceof Graduate){
//			System.out.println("a graduated student");
//			System.out.println("a student");
//			System.out.println("a person");
//		}else if(e instanceof Student){
//			System.out.println("a student");
//			System.out.println("a person");
//		}else{
//			System.out.println("a person");
//		}
		
		//方式二
		if(e instanceof Graduate){
			System.out.println("a graduated student");
		}
		
		if(e instanceof Student){
			System.out.println("a student");
		}
		
		if(e instanceof Person){
			System.out.println("a person");
		}
		
		
	}
}

class Person {
	protected String name = "person";
	protected int age = 50;

	public String getInfo() {
		return "Name: " + name + "\n" + "age: " + age;
	}
}

class Student extends Person {
	protected String school = "pku";

	public String getInfo() {
		return "Name: " + name + "\nage: " + age + "\nschool: " + school;
	}
}

class Graduate extends Student {
	public String major = "IT";

	public String getInfo() {
		return "Name: " + name + "\nage: " + age + "\nschool: " + school + "\nmajor:" + major;
	}
}
/*
Name: person
age: 50
school: pku
major:IT
a graduated student
a student
a person
*/
package com.atguigu.exer;

//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		Base1 base = new Sub1();//多态   Base1的属性,Sub1的方法
		base.add(1, 2, 3);

		Sub1 s = (Sub1)base;//强制提升 s为sub1的对象
		s.add(1,2,3);
	}
}

class Base1 {
	public void add(int a, int... arr) {
		System.out.println("base1");
	}
}

class Sub1 extends Base1 {

	public void add(int a, int[] arr) {
		System.out.println("sub_1");
	}

	public void add(int a, int b, int c) {
		System.out.println("sub_2");
	}

}
/*
sub_1
sub_2
*/

练习2

package com.atguigu.exer1;

public class Circle extends GeometricObject {

	private double radius;
	
	public Circle(double radius,String color, double weight) {
		super(color, weight);
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	public double findArea(){
		return 3.14 * radius * radius;
	}

}


package com.atguigu.exer1;

public class MyRectangle extends GeometricObject {

	private double width;
	private double height;
	
	public MyRectangle(double width,double height,String color, double weight) {
		super(color, weight);
		this.width = width;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	@Override
	public double findArea() {
		return width * height;
	}
}

package com.atguigu.exer1;

public class GeometricObject {//几何图形

	protected String color;
	protected double weight;
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	public GeometricObject(String color, double weight) {
		super();
		this.color = color;
		this.weight = weight;
	}
	
	public double findArea(){
		return 0.0;
	}
	
}

package com.atguigu.exer1;
/*
 * 
 * 定义一个测试类GeometricTest,
 * 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),
 * 编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。

 */
public class GeometricTest {

	public static void main(String[] args) {
		GeometricTest test = new GeometricTest();
		
		Circle c1 = new Circle(3.3, "white", 1.0);
		test.displayGeometricObject(c1);
		Circle c2 = new Circle(3.3, "white", 1.0);
		test.displayGeometricObject(c2);
		
		boolean isEquals = test.equalsArea(c1, c2);
		System.out.println("c1 和 c2的面积是否相等:" + isEquals);
		
		MyRectangle rect = new MyRectangle(2.1, 3.4, "red", 2.0);
		test.displayGeometricObject(rect);
		
	}
	
	public void displayGeometricObject(GeometricObject o){//GeometricObject o = new Circle(...)
		System.out.println("面积为:" + o.findArea());
	}
	
	//测试两个对象的面积是否相等
	public boolean equalsArea(GeometricObject o1,GeometricObject o2){
		return o1.findArea() == o2.findArea();
	}
}
/*
面积为:34.1946
面积为:34.1946
c1 和 c2的面积是否相等:true
面积为:7.14

*/

7、Object类的使用

java.lang.Object类

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

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

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

属性:无

方法:equals() / toString() / getClass() /hashCode() / clone() / finalize()

wait() 、 notify()、notifyAll()

4.Object类只声明了一个空参的构造器

面试题:

final、finally、finalize的区别?

package com.atguigu.java1;

public class ObjectTest {

	public static void main(String[] args) {		
		Order order = new Order();
		System.out.println(order.getClass().getSuperclass());
		
	}
}

class Order{
	
}
package com.atguigu.java1;


public class FinalizeTest {
	public static void main(String[] args) {
		Person p = new Person("Peter", 12);
		System.out.println(p);
		p = null;//此时对象实体就是垃圾对象,等待被回收。但时间不确定。
		System.gc();//强制性释放空间
	}
}

class Person{
	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = 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;
	}
	//子类重写此方法,可在释放对象前进行某些操作
	@Override
	protected void finalize() throws Throwable {
		System.out.println("对象被释放--->" + this);
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

/*
Person [name=Peter, age=12]
对象被释放--->Person [name=Peter, age=12]
*/
package com.atguigu.java1;

//Object类的clone()的使用
public class CloneTest {
	public static void main(String[] args) {
		Animal a1 = new Animal("花花");
		try {
			Animal a2 = (Animal) a1.clone();
			System.out.println("原始对象:" + a1);
			a2.setName("毛毛");
			System.out.println("clone之后的对象:" + a2);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
}

class Animal implements Cloneable{
	private String name;

	public Animal() {
		super();
	}

	public Animal(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

	@Override
	public String toString() {
		return "Animal [name=" + name + "]";
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n9rO2cxM-1616400648662)(E:\project\mp\java\day6-10\pic\image-20210318154708300.png)]

== 和 equals() 区别

一、回顾 == 的使用:

== :运算符

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

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

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

补充: == 符号使用时,必须保证符号左右两边的变量类型一致。

二、equals()方法的使用:

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

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

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

public boolean equals(Object obj) {
return (this == obj);
}

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

  1. 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是

两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。

  1. 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们

就需要对Object类中的equals()进行重写.

重写的原则:比较两个对象的实体内容是否相同.

package com.atguigu.java1;

import java.util.Date;

public class EqualsTest {
	public static void main(String[] args) {
		
		//基本数据类型
		int i = 10;
		int j = 10;
		double d = 10.0;
		System.out.println(i == j);//true
		System.out.println(i == d);//true
		
		boolean b = true;
//		System.out.println(i == b);
		
		char c = 10;
		System.out.println(i == c);//true
		
		char c1 = 'A';
		char c2 = 65;
		System.out.println(c1 == c2);//true
		
		//引用类型:
		Customer cust1 = new Customer("Tom",21);
		Customer cust2 = new Customer("Tom",21);
		System.out.println(cust1 == cust2);//false
		
		String str1 = new String("atguigu");
		String str2 = new String("atguigu");
		System.out.println(str1 == str2);//false
		System.out.println("****************************");
		System.out.println(cust1.equals(cust2));//false--->true
		System.out.println(str1.equals(str2));//true
		
		Date date1 = new Date(32432525324L);
		Date date2 = new Date(32432525324L);
		System.out.println(date1.equals(date2));//true
		
		
	}
}

package com.atguigu.java1;

public class Customer {
	
	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 Customer() {
		super();
	}
	public Customer(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	//自动生成的equals()
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Customer other = (Customer) 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;
	}
	
	
	
	//重写的原则:比较两个对象的实体内容(即:name和age)是否相同
	//手动实现equals()的重写
//	@Override
//	public boolean equals(Object obj) {
//		
		System.out.println("Customer equals()....");
//		if (this == obj) {
//            return true;
//        }
//		
//		if(obj instanceof Customer){
//			Customer cust = (Customer)obj;
//			//比较两个对象的每个属性是否都相同
			if(this.age == cust.age && this.name.equals(cust.name)){
				return true;
			}else{
				return false;
			}
//			
//			//或
//			return this.age == cust.age && this.name.equals(cust.name);
//		}else{
//			return false;
//			
//		}
//		
//	}
	//手动实现
//	@Override
//	public String toString() {
//		return "Customer[name = " + name + ",age = " + age + "]"; 
//	}
	//自动实现
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MFErfWf3-1616400648663)(E:\project\mp\java\day6-10\pic\image-20210318162628623.png)]

练习

编写Order类,有int型的orderId,String型的orderName,

相应的getter()和setter()方法,两个参数的构造器,

重写父类的equals()方法:public boolean equals(Object obj),

并判断测试类中创建的两个对象是否相等。

package com.atguigu.exer2;

public class OrderTest {
	public static void main(String[] args) {
		Order order1 = new Order(1001, "AA");
		Order order2 = new Order(1001, new String("BB"));
		
		System.out.println(order1.equals(order2));//false
		
		Order order3 = new Order(1001, "BB");
		System.out.println(order2.equals(order3));//true
		
//		String s1 = "BB";
//		String s2 = "BB";
//		System.out.println(s1 == s2);//true
		
	}
}


class Order{
	private int orderId;
	private String orderName;
	
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	public Order(int orderId, String orderName) {
		super();
		this.orderId = orderId;
		this.orderName = orderName;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		
		if(obj instanceof Order){
			Order order = (Order)obj;
			//正确的:
			return this.orderId == order.orderId && 
					this.orderName.equals(order.orderName);
			//错误的:
//			return this.orderId == order.orderId &&
//					this.orderName == order.orderName;
		}
		
		return false;
	}
}

实例2

package com.atguigu.exer2;

public class MyDateTest {
	public static void main(String[] args) {
        MyDate m1 = new MyDate(14, 3, 1976);
        MyDate m2 = new MyDate(14, 3, 1976);
        if (m1 == m2) {
            System.out.println("m1==m2");
        } else {
            System.out.println("m1!=m2"); // m1 != m2 指向不同地址空间
        }

        if (m1.equals(m2)) {
            System.out.println("m1 is equal to m2");// m1 is equal to m2
        } else {
            System.out.println("m1 is not equal to m2");
        }
    }

}

class MyDate{
	private int day;
	private int month;
	private int year;
	
	public MyDate(int day, int month, int year) {
		super();
		this.day = day;
		this.month = month;
		this.year = year;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		
		if(obj instanceof MyDate){
			MyDate myDate = (MyDate)obj;//强制类型转换
			return this.day == myDate.day && this.month == myDate.month &&
					this.year == myDate.year;
		}
		
		return false;

	}

//	@Override
//	public boolean equals(Object obj) {
//		if (this == obj)
//			return true;
//		if (obj == null)
//			return false;
//		if (getClass() != obj.getClass())
//			return false;
//		MyDate other = (MyDate) obj;
//		if (day != other.day)
//			return false;
//		if (month != other.month)
//			return false;
//		if (year != other.year)
//			return false;
//		return true;
//	}
	
	
}

toString()

Object类中toString()的使用:

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

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

public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}

2.像String、Date、File、包装类等都重写了Object类中的toString()方法。

使得在调用对象的toString()时,返回"实体内容"信息

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

package com.atguigu.java1;

import java.util.Date;


public class ToStringTest {
	public static void main(String[] args) {
		
		Customer cust1 = new Customer("Tom",21);
		System.out.println(cust1.toString());//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
		System.out.println(cust1);//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
		
		String str = new String("MM");
		System.out.println(str);//MM
		
		Date date = new Date(4534534534543L);
		System.out.println(date.toString());//Mon Sep 11 08:55:34 GMT+08:00 2113
		
	}
}

Customer类

package com.atguigu.java1;

public class Customer {
	
	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 Customer() {
		super();
	}
	public Customer(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	//自动生成的equals()
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Customer other = (Customer) 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;
	}
	
	
	
	//重写的原则:比较两个对象的实体内容(即:name和age)是否相同
	//手动实现equals()的重写
//	@Override
//	public boolean equals(Object obj) {
//		
		System.out.println("Customer equals()....");
//		if (this == obj) {
//            return true;
//        }
//		
//		if(obj instanceof Customer){
//			Customer cust = (Customer)obj;
//			//比较两个对象的每个属性是否都相同
			if(this.age == cust.age && this.name.equals(cust.name)){
				return true;
			}else{
				return false;
			}
//			
//			//或
//			return this.age == cust.age && this.name.equals(cust.name);
//		}else{
//			return false;
//			
//		}
//		
//	}
	
	//自动实现  重写toSting
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}
}

练习

父类GeometricObject

package com.atguigu.exer3;

public class GeometricObject {
	
	protected String color;
	protected double weight;
	public GeometricObject() {
		super();
		this.color = "white";
		this.weight = 1.0;
	}
	public GeometricObject(String color, double weight) {
		super();
		this.color = color;
		this.weight = weight;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	
	
}

子类

package com.atguigu.exer3;

public class Circle extends GeometricObject {
	
	private double radius;

	public Circle() {
		super();
		radius = 1.0;
//		color = "white";
//		weight = 1.0;
	}

	public Circle(double radius) {
		super();
		this.radius = radius;
	}
	public Circle(double radius,String color,double weight) {
		super(color,weight);
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	//求圆的面积
	public double findArea(){
		return 3.14 * radius * radius;
	}
	//比较两个圆的半径是否相等,如相等,返回true。
	@Override
	public boolean equals(Object obj) {
		
		if(this == obj){
			return true;
		}
		
		if(obj instanceof Circle){
			Circle c = (Circle)obj;
			return this.radius == c.radius;
		}
		
		return false;
		
	}

	@Override
	public String toString() {
		return "Circle [radius=" + radius + "]";
	}
	
	
}

测试

package com.atguigu.exer3;
/*
 * 写一个测试类,创建两个Circle对象,判断其颜色是否相等;
 * 利用equals方法判断其半径是否相等;利用toString()方法输出其半径。
 */
public class CircleTest {
	public static void main(String[] args) {
		
		Circle circle1 = new Circle(2.3);
		Circle circle2 = new Circle(3.3, new String("white"), 2.0);
		
		System.out.println("颜色是否相等:" + circle1.getColor().equals(circle2.getColor()));
		
		System.out.println("半径是否相等:" + circle1.equals(circle2));
		
		System.out.println(circle1);
		System.out.println(circle2.toString());
		
	}
}

8、 包装类(Wrapper)的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ey8QehpP-1616400648664)(E:\project\mp\java\day6-10\pic\image-20210320170655819.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zSlARUFs-1616400648665)(E:\project\mp\java\day6-10\pic\image-20210320170811892.png)]

//基本数据类型 —>包装类:调用包装类的构造器

	@Test
	public void test1(){
		
		int num1 = 10;
//		System.out.println(num1.toString());
		Integer in1 = new Integer(num1);
		System.out.println(in1.toString());//10
		
		Integer in2 = new Integer("123");
		System.out.println(in2.toString());//123
		
		//报异常
//		Integer in3 = new Integer("123abc");
//		System.out.println(in3.toString());
		
		Float f1 = new Float(12.3f);
		Float f2 = new Float("12.3");
		System.out.println(f1);//12.3
		System.out.println(f2);//12.3
		
		Boolean b1 = new Boolean(true);
		Boolean b2 = new Boolean("TrUe");
		System.out.println(b2);//true
		Boolean b3 = new Boolean("true123");
		System.out.println(b3);//false
		
		
		Order order = new Order();
		System.out.println(order.isMale);//false
		System.out.println(order.isFemale);//null
	}
	

class Order{
	
	boolean isMale;//boolean类型,默认flase
	Boolean isFemale;
}

//包装类—>基本数据类型:调用包装类Xxx的xxxValue()


	@Test
	public void test2(){
		Integer in1 = new Integer(12);
		
		int i1 = in1.intValue();
		System.out.println(i1 + 1);
		
		
		Float f1 = new Float(12.3);
		float f2 = f1.floatValue();
		System.out.println(f2 + 1);
	}

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

public void test3(){
//		int num1 = 10;
//		//基本数据类型-->包装类的对象
//		method(num1);
		
		//自动装箱:基本数据类型 --->包装类
		int num2 = 10;
		Integer in1 = num2;//自动装箱
		
		boolean b1 = true;
		Boolean b2 = b1;//自动装箱
		
		//自动拆箱:包装类--->基本数据类型
		System.out.println(in1.toString());
		
		int num3 = in1;//自动拆箱
		
	}

//基本数据类型、包装类—>String类型:调用String重载的valueOf(Xxx xxx)

	@Test
	public void test4(){
		
		int num1 = 10;
		//方式1:连接运算
		String str1 = num1 + "";
		//方式2:调用String的valueOf(Xxx xxx)
		float f1 = 12.3f;
		String str2 = String.valueOf(f1);//"12.3"
		
		Double d1 = new Double(12.4);
		String str3 = String.valueOf(d1);
		System.out.println(str2);
		System.out.println(str3);//"12.4"
		
	}

//String类型 —>基本数据类型、包装类:调用包装类的parseXxx(String s)

	@Test
	public void test5(){
		String str1 = "123";
		//错误的情况:
//		int num1 = (int)str1;
//		Integer in1 = (Integer)str1;
		//可能会报NumberFormatException
		int num2 = Integer.parseInt(str1);
		System.out.println(num2 + 1);//124
		
		String str2 = "true1";
		boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);//false
	}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FEN3o1HA-1616400648665)(E:\project\mp\java\day6-10\pic\image-20210320173146968.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywGAeXEu-1616400648666)(E:\project\mp\java\day6-10\pic\image-20210320173508406.png)]

练习

@Test
	public void test1() {
		Object o1 = true ? new Integer(1) : new Double(2.0);
		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内部定义了IntegerCache结构,IntegerCache中定义了Integer[],
		//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在
		//-128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率
		
		Integer m = 1;
		Integer n = 1;
		System.out.println(m == n);//true

		Integer x = 128;//相当于new了一个Integer对象
		Integer y = 128;//相当于new了一个Integer对象
		System.out.println(x == y);//false 两个对象
	}

练习2

利用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等

package com.atguigu.exer4;

import java.util.Scanner;
import java.util.Vector;


public class ScoreTest {
	public static void main(String[] args) {
		//1.实例化Scanner,用于从键盘获取学生成绩
		Scanner scan = new Scanner(System.in);
		
		//2.创建Vector对象:Vector v=new Vector();相当于原来的数组
		Vector v = new Vector();
		
		//3.通过for(;;)或while(true)方式,给Vector中添加数组
		int maxScore = 0;
		for(;;){
			System.out.println("请输入学生成绩(以负数代表输入结束)");
			int score = scan.nextInt();
			//3.2 当输入是负数时,跳出循环
			if(score < 0){
				break;
			}
			if(score > 100){
				System.out.println("输入的数据非法,请重新输入");
				continue;
			}
			//3.1 添加操作::v.addElement(Object obj)
			//jdk5.0之前:
//			Integer inScore = new Integer(score);
//			v.addElement(inScore);//多态
			//jdk5.0之后:
			v.addElement(score);//自动装箱
			//4.获取学生成绩的最大值
			if(maxScore < score){
				maxScore = score;
			}
		}
		
		//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
		char level;
		for(int i = 0;i < v.size();i++){
			Object obj = v.elementAt(i);
			//jdk 5.0之前:
//			Integer inScore = (Integer)obj;
//			int score = inScore.intValue();
			//jdk 5.0之后:
			int score = (int)obj;
			
			if(maxScore - score <= 10){
				level = 'A';
			}else if(maxScore - score <= 20){
				level = 'B';
			}else if(maxScore - score <= 30){
				level = 'C';
			}else{
				level = 'D';
			}
			
			System.out.println("student-" + i + " score is " + score + ",level is " + level);
			
		}	
		
	}
}

seInt(str1);
System.out.println(num2 + 1);//124

	String str2 = "true1";
	boolean b1 = Boolean.parseBoolean(str2);
	System.out.println(b1);//false
}

[外链图片转存中...(img-FEN3o1HA-1616400648665)]

[外链图片转存中...(img-ywGAeXEu-1616400648666)]

## 练习

```java
@Test
	public void test1() {
		Object o1 = true ? new Integer(1) : new Double(2.0);
		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内部定义了IntegerCache结构,IntegerCache中定义了Integer[],
		//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在
		//-128~127范围内时,可以直接使用数组中的元素,不用再去new了。目的:提高效率
		
		Integer m = 1;
		Integer n = 1;
		System.out.println(m == n);//true

		Integer x = 128;//相当于new了一个Integer对象
		Integer y = 128;//相当于new了一个Integer对象
		System.out.println(x == y);//false 两个对象
	}

练习2

利用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等

package com.atguigu.exer4;

import java.util.Scanner;
import java.util.Vector;


public class ScoreTest {
	public static void main(String[] args) {
		//1.实例化Scanner,用于从键盘获取学生成绩
		Scanner scan = new Scanner(System.in);
		
		//2.创建Vector对象:Vector v=new Vector();相当于原来的数组
		Vector v = new Vector();
		
		//3.通过for(;;)或while(true)方式,给Vector中添加数组
		int maxScore = 0;
		for(;;){
			System.out.println("请输入学生成绩(以负数代表输入结束)");
			int score = scan.nextInt();
			//3.2 当输入是负数时,跳出循环
			if(score < 0){
				break;
			}
			if(score > 100){
				System.out.println("输入的数据非法,请重新输入");
				continue;
			}
			//3.1 添加操作::v.addElement(Object obj)
			//jdk5.0之前:
//			Integer inScore = new Integer(score);
//			v.addElement(inScore);//多态
			//jdk5.0之后:
			v.addElement(score);//自动装箱
			//4.获取学生成绩的最大值
			if(maxScore < score){
				maxScore = score;
			}
		}
		
		//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
		char level;
		for(int i = 0;i < v.size();i++){
			Object obj = v.elementAt(i);
			//jdk 5.0之前:
//			Integer inScore = (Integer)obj;
//			int score = inScore.intValue();
			//jdk 5.0之后:
			int score = (int)obj;
			
			if(maxScore - score <= 10){
				level = 'A';
			}else if(maxScore - score <= 20){
				level = 'B';
			}else if(maxScore - score <= 30){
				level = 'C';
			}else{
				level = 'D';
			}
			
			System.out.println("student-" + i + " score is " + score + ",level is " + level);
			
		}	
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值