Java基础5.面向对象(中)

目录

一、面向对象的特征之二:继承性

1.为什么要有类的继承性?(继承性的好处)

 2.继承性的格式

3.子类继承父类以后有哪些不同?

4.Java中继承性的说明

5.java.lang.Object类的理解 

二、方法的重写

1.什么是方法的重写(override 或 overwrite)?

2. 应用: 

3.举例:

4.重写的规则: 

5.面试题: 

5.1区分方法的重写和重载?

三、关键字:super

1、理解

2.可以用来调用的结构:

3.super调用属性、方法:

 4.super调用构造器:

四、子类对象实例化全过程

1.从结果上看:继承性

 2.从过程上看:

 3.强调说明:

 4思考: 

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

1.多态性的理解:

2.何为多态性:

3.多态性的使用:

4.多态性的使用前提:

5.多态性的应用举例:

 6.多态性使用的注意点:(对谁使用)

7.关于向上转型与向下转型: 

7.1 向上转型

7.2 向下转型

        7.2.1 为什么使用向下转型:

        7.2.2 如何实现向下转型:

        7.2.3 使用时的注意点:

         7.2.4 instanceof的使用:

         7.2.5 图示:

 8. 面试题:

8.1 谈谈你对多态性的理解?

8.2 多态是编译时行为还是运行时行为? 

六、Object类的使用

1.java.lang.Object类的说明:

 2.equals()方法

2.1 equals()的使用:

2.2 如何重写equals() 

2.3 回顾 == 运算符的使用:

3. toString()方法

3.1 toString()的使用:

 3.2 如何重写toString()

4.面试题:

4.1final、finally、finalize的区别?

4.2 == 和 equals()区别?

七、单元测试方法

八、包装类的使用

1.为什么要有包装类(或封装类)

2.基本数据类型与对应的包装类:

3.需要掌握的类型间的转换:(基本数据类型、包装类、String)

九、练习题


一、面向对象的特征之二:继承性

1.为什么要有类的继承性?(继承性的好处)

 ①减少代码冗余,提高了代码的复用性。
 ②便于功能的扩展。
 ③为之后多态性的使用,提供前提。

图示:

 2.继承性的格式

class A extends B{
      //A:子类、派生类、subclass
      //B类:父类、超类、基类、superclass

}

3.子类继承父类以后有哪些不同?

3.1体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
特别的:父类中声明为private的属性或方法,子类继承父类以后,仍认为获取了父类中私的结构。
               只因为封装性的影响,使得子类不能直接调用父类的结构而已。

3.2子类继承父类以后,还可以声明自己特的属性或方法:实现功能的拓展。
      子类和父类的关系,不同于子集和集合的关系。
      extends:延展、扩展

4.Java中继承性的说明

1.一个类可以被多个子类继承。
2.Java中类的单继承性:一个类只能有一个父类
3.子父类是相对的概念。
4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类。
5.子类继承父类以后,就获取了直接父类以及所的间接父类中声明的属性和方法

图示:

5.java.lang.Object类的理解 

1.如果我们没显式的声明一个类的父亲的话,则此类继承于java.lang.Object类
2.所的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
3.意味着,所的java类具java.lang.Object类声明的功能

二、方法的重写

1.什么是方法的重写(override 或 overwrite)?

子类继承父类以后,可以对父类中同名同参数方法,进行覆盖操作

2. 应用: 

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

3.举例:

class Circle{
public double findeArea(){}//求面积
}
class Cylinder extends Circle{
public double findeArea(){}//求表面积
}
************************
class Account{
public boolean withfraw(double amt){}
}
class CheckAccount extends Account{
public boolean withdraw(double amt){}
}

4.重写的规则: 

方法的声明:权限修饰符 返回值类型 方法名(形参列表throws 异常的类型{
                                  //方法体
                          }
              约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
      >特殊的:子类不能重写父类中声名为private权限的方法
③ 返回值类型:
      >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
      >父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类。
      >父类被重写的方法的返回值类型是基本数据类型(比如:double,则子类重写的方法的返回值必须是相同的基本数据类型(必须也是double)
 ④ throws 异常的类型:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
注意:
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。 

5.面试题: 

5.1区分方法的重写和重载?

①二者的概念:

重载:定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数              类型不同即可。构造器可以重载

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


②重载、重写的具体规则:

重载:总结:“两同一不同”:同一类,相同的方法名
                                 参数列表不同:①参数个数不同,②参数类型不同

重写:

① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
      >特殊的:子类不能重写父类中声名为private权限的方法
③ 返回值类型:
    >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
    >父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类。
    >父类被重写的方法的返回值类型是基本数据类型(比如:double,则子类重写的方法的返回值必须是相同的基本数据类型(必须也是double)
④ throws 异常的类型:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

 ③ 重载:不表现为多态性。
      重写:表现为多态性。

重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类 和子类的,即子类可以重载父类的同名不同参数的方法。 

所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。 
引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”

三、关键字:super

1、理解

super 关键字可以理解为:父类的

2.可以用来调用的结构:

属性、构造器、方法

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(形参列表)",调用父类中的          构造器。

四、子类对象实例化全过程

1.从结果上看:继承性

>子类继承父类以后,就获取了父类中的声明的属性或方法
>创建子类的对象,在堆空间中,就会加载所父类中声明的属性。

 2.从过程上看:

当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器....
直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所的父类的结构,所以才可以看到内存中父类中的结构,子类对象才可以考虑进行调用。

图示:

 

 
3.强调说明:

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

 4思考: 

(1).为什么super(…)和this(…)调用语句不能同时在一个构造器中出现? 
因为super()和this(),调用构造器都要放在首行,所以二者之间只能选一个
(2).为什么super(…)或this(…)调用语句只能作为构造器中的第一句出现?
无论通过那个构造器创建子类对象,需要保证先初始化父类
目的:当子类继承父类后,“继承”父类中所有的属性和方法,因此子类有必要知道父类如何为对象初始化。

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

1.多态性的理解:

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

2.何为多态性:

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

举例:

Person p = new Man();
Objuct obj = new Date();

3.多态性的使用:

>多态性的使用:虚拟方法调用

>有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,我们
  实际执行的是子类重写父类的方法。
>总结:编译,看左边。运行,看右边。

4.多态性的使用前提:

① 要类的继承关系 ② 方法的重写

5.多态性的应用举例:

举例一:
public void func(Animal animal) {//Animal animal = new Dog();
        animal.eat();
        animal.shout();
    }
举例二:
class Order{
    public void method(Object obj) {
        
    }
}
举例三:MySQL/Oracle传哪个对象就能调用那个对象的对应的方法,
class Driver{
    public void doDate(Connection conn) {//conn = new MySQLConnection()/new OracleConnection();
        //规范的步骤去操作数据
//        conn.method();
//        conn.method();
//        conn.method();
    }
}

详细见如下代码:

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();
		}
	}
	
	//多态性省略了以下方法,只用一个func(Animal animal)都可以调用
//	public void func(Dog dog) {//只能new Dof();的对象
//		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) {
		
	}
}

/*
 * 举例三:MySQL/Oracle传那个对象就能调用那个对象的对应的方法,
 */
class Driver{
	public void doDate(Connection conn) {//conn = new MySQLConnection()/new OracleConnection();
		//规范的步骤去操作数据
//		conn.method();
//		conn.method();
//		conn.method();
	}
}





 6.多态性使用的注意点:(对谁使用)

对象的多态性:>只适用于方法(编译看左边,运行看右边)

                       >不适用于属性(编译运行都看左边)

7.关于向上转型与向下转型: 

7.1 向上转型

向上转型:多态

7.2 向下转型

7.2.1 为什么使用向下转型:

了对象的多态性以后,内存中实际上是加载了子类特的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特的属性和方法不能调用。
如何才能调用子类特的属性和方法?使用向下转型

7.2.2 如何实现向下转型:

 使用强制类型转换符:()

7.2.3 使用时的注意点:

①使用强转时,可能出现ClassCastException的异常。
②为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。

 7.2.4 instanceof的使用:

①a instanceof A:判断对象a是否为类A的实例,如果是,返回true。如果不是,返回false;
②如果a instanceof A返回true,则a instanceof B也会返回true,其中,类B是类A的父类。
③要求a所属的类与类A必须是子类和父类的关系,否则编译错误。

 7.2.5 图示:

 8. 面试题:

8.1 谈谈你对多态性的理解?

①实现代码的通用性。
②Object类中定义的public boolean equals(Object obj){}

    JDBC:使用java程序操作(获取数据库连接、CRUD)数据库(MySql、Oracle、DB2、

               Sql Server)
③抽象类、接口的使用肯定体现了多态性。(抽象类、接口不能实例化)

8.2 多态是编译时行为还是运行时行为? 

多态是运行时行为

证明:见以下代码

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();
		 
	}

}
*******************************************************************************8
package com.atguigu.java5;
//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		Base base = new Sub();
		base.add(1, 2, 3);

//		Sub s = (Sub)base;
//		s.add(1,2,3);
	}
}

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

class Sub extends Base {

	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");
//	}

}

六、Object类的使用

1.java.lang.Object类的说明:

 1.Object类是所Java类的根父类
 2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
 3.Object类中的功能(属性、方法就具通用性
      属性:无
      方法:equals() / toString () / getClass() / hashCoder() / clone() / finalize() 
           wait() 、notify()、notifyAll()
  
 4.Object类只声明了一个空参构造器。

 2.equals()方法

2.1 equals()的使用:

1.是一个方法,而非运算符
 2.只能够适用于引用数据类型
 3.Object类中equals()的定义:
       public boolean equals(Object obj) {
          return (this == obj);
     }
     说明:Object类中定义的equals()和 == 的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
4.想String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后,比较的       不是两个引用的地址值是否相同,而是比较两个对象的“实体内容”是否相同
 5.通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的 “实体内         容”是否相同。
   那么,我们就需要对Object类中的equals()方法进行重写
   重写的原则,比较两个对象的实体内容是否相同。

2.2 如何重写equals() 

2.2.1 手动重写举例:

//重写原则,比较两个对象的实体内容(即,name和age)是否相同
	//手动实现equals()的重写
	//@Override
	public boolean equals(java.lang.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 == cust.name) {
//				return true;
//			}else {
//				return false;
//			}
			//或
			return this.age == cust.age &&  this.name.equals(cust.name);
		
		}else {
		    return false;
		}
		
	}

2.2.2 开发中如何实现:自动生成

//自动生成equals()重写:工具栏Source--->Generate hashCode() and equals()...
	@Override
	public boolean equals(java.lang.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;
	}
	

举例: 

package com.atguigu.java1;
/*
 * 面试题: == 和 equals()区别
 * 一、回顾 == 的使用:
 * 
 * == :运算符
 * 1. 可以使用在基本数据类型变量和引用数据类型变量中
 * 2. 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一点类型相同)
 * 	     如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。即两个引用是否指向同一个对象实体。	
 * 	补充:引用数据类型 == 符号使用时,必须保证符号左右两边的变量类型一致。  
 * 
 * 
 *二、equals()方法的使用
 *1.是一个方法,而非运算符
 *2.只能够适用于引用数据类型
 *3.Object类中equals()的定义:
 *	  public boolean equals(Object obj) {
          return (this == obj);
     }
 *         说明:Object类中定义的equals()和 == 的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
 * 4.想String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后,比较的不是
 *          两个引用的地址值是否相同,而是比较两个对象的“实体内容”是否相同
 * 
 *5.通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的 “实体内容”是否相同。
 *	那么,我们就需要对Object类中的equals()方法进行重写
 *	重写的原则,比较两个对象的实体内容是否相同。
 * 
 */
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;//'A'=65; 'a' =97;
		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
		
		
	}
}

//---------------------------------------------------------------------------------
package com.atguigu.java1;

public class Customer {
	
	private String name;
	private int age;
	
	public Customer() {
		super();
	}
	public Customer(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;
	}
	//重写原则,比较两个对象的实体内容(即,name和age)是否相同
	//手动实现equals()的重写
	//@Override
//	public boolean equals(java.lang.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 == cust.name) {
				return true;
			}else {
				return false;
			}
//			//或
//			return this.age == cust.age && this.name == cust.name;
//		
//		}else {
//			return false;
//		}
//		
//	}
	//自动生成equals()重写:工具栏Source--->Generate hashCode() and equals()...
	@Override
	public boolean equals(java.lang.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;
	}

 

2.3 回顾 == 运算符的使用:

1. 可以使用在基本数据类型变量和引用数据类型变量中
2. 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一定类型相同)
    如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。即两个引用是否指向同一        个对象实体。    
   补充:引用数据类型 == 符号使用时,必须保证符号左右两边的变量类型一致。

3. toString()方法

3.1 toString()的使用:

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

2.Object类中toString()的定义
        public String toString() {
                return getClass().getName() + "@" + Integer.toHexString(hashCode());
         }

3.像String、Date、File、包装类等都重写了Object类中的toString()方法
    使得在调用对象的toString()方法时,返回“实体内容”信息
  
4.自定义类也可以重写toString()方法,当调用此方法时,返回对象的“实体内容”

 3.2 如何重写toString()

//自动生成toString()方法的重写   工具栏Source--->Generate toString() 
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}

举例:

package com.atguigu.java1;

import java.util.Date;

/*
 * 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 ToString {
	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
		
		String str = new String("MM");
		System.out.println(str);//MM
		System.out.println(str.toString());//MM
		
		Date date = new Date(45615671L);
		System.out.println(date.toString());//Thu Jan 01 20:40:15 CST 1970
		System.out.println(date);//Thu Jan 01 20:40:15 CST 1970
	}
}


//----------------------------------------------------------------------------------


package com.atguigu.java1;

public class Customer {
	
	private String name;
	private int age;
	
	public Customer() {
		super();
	}
	public Customer(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;
	}
	//重写原则,比较两个对象的实体内容(即,name和age)是否相同
	//手动实现equals()的重写
	//@Override
//	public boolean equals(java.lang.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 == cust.name) {
				return true;
			}else {
				return false;
			}
//			//或
//			return this.age == cust.age && this.name == cust.name;
//		
//		}else {
//			return false;
//		}
//		
//	}
	//自动生成equals()重写:工具栏Source--->Generate hashCode() and equals()...
	@Override
	public boolean equals(java.lang.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;
	}
	
	//手动生成toString()重写
//	@Override
//	public String toString() {
//		
//		return "Customer[name ="+name+",age ="+age+"]";
//	}
	
	//自动生成toString()方法的重写   工具栏Source--->Generate toString() 
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}
	
}

4.面试题:

4.1final、finally、finalize的区别?

final:

修饰--类,方法,变量。

        类:不可被继承。

        方法:不可被重写。

        变量:初始化时给定值,以后不得修改。

finally:

是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。

finalize:

方法名, java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
————————————————
版权声明:本文为CSDN博主「Matrix_Dev」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youxia007ya/article/details/81006602

 

4.2 == 和 equals()区别?

==:

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

2. 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一点类型相同)如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。即两个引用是否指向同一个对象实体。

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

equals()方法的使用:

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

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

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

  public boolean equals(Object obj) {

          return (this == obj);

     }

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

4.想String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用的地址值是否相同,而是比较两个对象的“实体内容”是否相同

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

  那么,我们就需要对Object类中的equals()方法进行重写

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

七、单元测试方法

步骤:
  1.中当前工程 - 右键择:build path - add libraries - Junit4 - 下一步
  2.创建一个Java,进行单元测试
           此时Java类要求:①此类是public的 ②此类提供的无参的构造器
  3.此类中声明单元测试方法
        此时的单元测试方法:方法的权限是public,没返回值,没形参
  
  4.此单元测试方法上需要声明注释:@Test,并在单元测试类中导入:import org.junit.Test;
  
  5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
  6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
  
  
   说明:
   1.如果执行结果没任何异常:绿条
   2.如果执行结果出现异常:红条

举例:

 

package com.atguigu.java;

import org.junit.Test;

public class ReviewTest {

	//关于toString()方法
	@Test
	public void test3() {
		String s = "abc";
		s = null;
		System.out.println(s);//null
		System.out.println("**********");
		System.out.println(s.toString());//出现NullPointerException
	}
	//手动写的equals()和自动生成的equals()的区别
	@Test
	public void test2() {
		Person p = new Person("Tom",12);
		Man m = new Man("Tom", 12);
		
		System.out.println(p.equals(m));
	}
	
	
	
	//数组也作为Object类的子类出现,可以调用Object类中声名的方法
	@Test
	public void test1() {
		int[] arr = new int[] {1,2,};
		print(arr);
		
		System.out.println(arr.getClass().getSuperclass());
	}
	
	public void print(Object obj) {
		System.out.println(obj);
	}
}

八、包装类的使用

1.为什么要有包装类(或封装类)

为了使得基本数据类型的变量具类的特征,引入包装类。

2.基本数据类型与对应的包装类:

 

3.需要掌握的类型间的转换:(基本数据类型、包装类、String)

 简易版:

基本数据类型<---->包装类:JDK 5.0新特性:自动装箱与自动拆箱

/*
	 * JDK 5.0新特性:自动装箱与自动拆箱
	 */
	@Test
	public void test3() {
		int num1 = 10;
		
		//要想将num1放到method()方法,就要将num1装换成包装类
		//基本数据类型 --->包装类的对象
		Integer in1 = new Integer(num1);
		method(in1);
		
		//method(num1);//自动装箱与自动拆箱
		//自动装箱:本数据类型 --->包装类
		int num2 = 11;
		Integer in2 = num2;//自动装箱
		
		boolean b1 = true;
		Boolean b2 = b1;//自动装箱
		System.out.println(b2.toString());
		
		//自动拆箱:包装类 --->基本数据类型
		System.out.println(in1.toString());
		
		int num3 = in1;//自动拆箱
		System.out.println(num3);
	}

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

//基本数据类型、包装类--->String类型:调用String重载的valueOf(Xxx xxx)
	@Test
	public void test4() {
		
		int num1 = 10;
		//方式1:连接运算
		String str1 = num1 +"";
		System.out.println(str1);//"10"			
		//方式2:
		float f1 = 12.3f;
		String str2 = String.valueOf(f1);
		System.out.println(str2);//"12.3"	
		
		Double d1 = new Double(12.4);
		 String str3 = String.valueOf(d1);
		 System.out.println(str3);//"12.4"
	}

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

//String类型---->基本数据类型、包装类:调用包装类的parseXxx()
	@Test
	public void test5() {
		String str = "123";
		//错误情况:
//		int num1 = (int)str;
//		Integer in1 = (Integer)str1;
		
		int num2 = Integer.parseInt(str);
		System.out.println(num2+1);//124
		
		//错误情况:NumberFormatException: For input string: "123a"
//		String s = "123a";
//		int num1 = Integer.parseInt(s);
//		System.out.println(num1);
		
		String str1 = "false";
		boolean b3 = Boolean.parseBoolean(str1);
		System.out.println(b3);//false
		
		String str2 = "true";
		Boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);//true
		
		String str3 = "true123";
		boolean b2 = Boolean.parseBoolean(str3);
		System.out.println(b2);//false
	}


          注意:转换时,可能会报NumberFormatException异常

代码演示:

//基本数据类型 ---->包装类:调用包装类的构造器
	@Test
	public void test1() {
		
		int num1 = 10;
//		System.out.println(num1.toString());
		Integer in1 = new Integer(num1);
		System.out.println(in1.toString());
		
		Integer in2 = new Integer("123");
		System.out.println(in2.toString());
		
		//报异常
//		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);
		System.out.println(f2);
		
		//boolean中,只要不是true,其他的都是false
		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:Boolean isFemale;Boolean是类
		

 

//包装类--->基本数据类型:调用包装类的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);
	}

应用场景举例:

①Vector类中关于添加元素,只定义了形参为Object类型的方法:
v.addElement(Object obj)//基本数据类型-->包装类-->使用多态

九、练习题

5.面向对象习题(中)_chasing鱼的博客-CSDN博客 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值