返回顶部
扩大
缩小

Heaton

第5章 面向对象(中)

5、面向对象(中)
5.1 面向对象特征之二:继承性 2课时
5.2 方法的重写(override) 1课时
5.3 四种访问权限修饰符 1课时
5.4 关键字super 2课时
5.5 子类对象实例化过程 2课时
5.6 面向对象特征之三:多态性 1课时
5.7 Object类的使用 1课时
5.8 包装类的使用 1课时

5-1 面向对象特征之二:继承性






案例

	public class Person {
		
		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("吃饭");
	//		walk();
		}
		
		
		public void eat(String food){
			System.out.println("喜欢吃" + food);
		}
		
		
		private void walk(){
			System.out.println("走路");
		}
		
		
		public int getAge() {
			return age;
		}
		public void setAge(int age) {
			this.age = age;
		}
		
		public void display() throws Exception{
			
		}
		
		public java.lang.Object info(){
			
			return null;
		}
		
		public int get(){
			
			return 1;
		}
		
		public static  void method(){
			
		}
		
		public void show(String s,int a,double f){
			
		}
		
		
	}

	public class Student extends Person {

		// String name;
		// int age;
		String major;

		public Student() {
		}

		public Student(String major) {
			this.major = major;
		}

		// public void eat(){
		// System.out.println("吃饭");
		// }
		//
		// public void walk(){
		// System.out.println("走路");
		// }
		public void study() {
			System.out.println("学习");
		}

		public void eat() {
			System.out.println("学生应该多吃有营养的食物");
		}

		public void display() throws RuntimeException {

		}

		public int walk() {

			return 0;
		}

		public String info() {

			return "AA";
		}

		// public short get(){
		//
		// return 1;
		// }

		// 此方法不是对父类同名同参数方法的覆盖。
		public static void method() {

		}

		// 直接粘贴父类的方法的声明,然后子类进行重写即可。
		// public void show(String s,int a,double f){
		//
		// }

		@Override
		public void show(String s, int a, double f) {
				
		}

	}

			/**
	 * 面向对象的特征二:继承性   what? why? how?
	 * 
	 * 1.继承性的好处:①减少了代码的冗余,提高了代码的复用性;②更好的扩展性 ③为多态性的使用提供了前提
	 * 
	 * 2.格式:class A extends B.    extends:继承,(延展、扩展)
	 *        子类(SubClass):A
	 *        父类(SuperClass、超类、基类):B
	 *        
	 *        衡量: A is a B。
	 *        
	 * 3. 说明:子类A继承父类B以后,就获取了父类中声明的结构:属性、方法。 
	 *     3.1 不管父类中的属性或方法的权限为何,子类都可以获取到。 
	 *     3.2 但是由于封装性的影响,可能在子类中不能直接调用父类中权限较小的属性或方法。    
	 * 
	 * 4. 子类可以在继承父类的基础之上,再提供自己特有的属性或方法。
	 *    区别于:集合 与 子集
	 * 
	 * 5. 5.1 子类和父类是相对的概念。
	 *    5.2 子类通过继承,可以获取直接父类以及所有的间接父类中声明的所有的属性和方法。
	 *    5.3 一个父类可以被多个子类所继承。
	 *    5.4 子类只能声明一个父类。---->java类是单继承的!
	 *    
	 * 6. 
	 * 6.1 如果一个类没有显式继承另外一个类的话,则其父类为:java.lang.Object类
	 * 6.2 任何一个类(除了java.lang.Object类)都直接或间接的继承于java.lang.Object类
	 * 6.3 任何一个类在继承java.lang.Object类之后,就获取了Object类中声明的属性和方法。
	 * 
	 *
	 */
	public class ExtendsTest {
		public static void main(String[] args) {
			Person p1 = new Person();
			p1.name = "Tom";
			p1.eat();
			
			
			Student s = new Student();
			s.name = "Jerry";
	//		s.age = 2;
	//		s.age1 = 3;
			
			s.setAge(2);
			System.out.println(s.getAge());
			s.eat();
			
			System.out.println(p1.toString());
			//获取对象所属类的父类
			System.out.println(p1.getClass().getSuperclass());
			System.out.println(s.getClass().getSuperclass());
			
		}
	}






案例

	/**
	 *  1.(1)定义一个ManKind类,包括
	成员变量int sex和int salary;
	方法void manOrWorman():根据sex的值显示“man”(sex==1)或者“women”(sex==0);
	方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
	   (2)定义类Kids继承ManKind,并包括
	成员变量int yearsOld;
	方法printAge()打印yearsOld的值。
	   (3)在KidsTest类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。
	 */
	public class KidsTest {
		public static void main(String[] args) {
			Kids someKid = new Kids();
			
			someKid.employeed();
			someKid.manOrWoman();
			someKid.printAge();
			
	//		someKid.yearsOld = 10;
			
			someKid.setSex(1);
			someKid.setSalary(1000);
			someKid.setYearsOld(10);
			
			someKid.employeed();
			someKid.manOrWoman();
			someKid.printAge();
			
		}
	}

	class Kids extends ManKind{
		private int 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;
		}
		//结合下面方法的重写一起做
		public void employeed(){
			System.out.println("Kids should study and no job.");
		}
		
		
	}

	class ManKind{
		private int sex;
		private int 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!");
			}
		}

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



案例

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

		public double getRadius() {
			return radius;
		}

		public void setRadius(double radius) {
			this.radius = radius;
		}
		
		/**
		 * 求圆的面积
		 */
		public double findArea(){
			return 3.14 * radius * getRadius();
		}
		
		
	}

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

		public double getLength() {
			return length;
		}

		public void setLength(double length) {
			this.length = length;
		}
		/**
		 * 求圆柱的体积
		 */
		public double findVolume(){
			
	//		return 3.14 * getRadius() * getRadius() * this.length;
			
			return super.findArea() * length;
			
		}
		
		/**
		 * 计算圆柱的表面积
		 */
		public double findArea(){
			return 3.14 * getRadius() * getRadius() * 2 + 3.14 * 2 * getRadius() * getLength();
		}
		
	}

	public class CylinderTest {
		public static void main(String[] args) {
			Cylinder c = new Cylinder();
			double volume = c.findVolume();
			System.out.println(volume);
		}
	}

5-2 方法的重写(override)



案例

	/**
	 * 方法的重写(override / overwrite)
	 * 1.定义:子类在继承了父类以后,可以对父类中的同名同参数的方法进行“覆盖”或“覆写”。
	 * 
	 * 2.重写以后,如果我们创建子类的对象,通过子类的对象调用子父类中同名同参数的方法,执行的是子类重写父类的方法。
	 * 
	 * 3.  概念:子类重写的方法;父类被重写的方法
	 *     方法的声明: 权限修饰符  返回值类型  方法名(形参列表) throws 异常的类型 { }
	 *     
	 *     >子类重写的方法 与 父类被重写的方法的方法名和形参列表都相同
	 *     >子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
	 *        特别的,子类不能重写父类中声明为private的方法。
	 *     >子类重写的方法的返回值类型 不大于 父类被重写的方法的返回值类型。
	 *        举例:1.父类方法的返回值类型是void,子类要想重写,一定也是void
	 *             2.父类方法的返回值类型是类型A,子类重写父类方法,返回值类型可以是类型A或类型A的子类.不能是类型A的父类
	 *     >*子类重写的方法抛出的异常类型 不大于  父类被重写的方法抛出的异常类型
	 *     
	 *     *****************************
	 *     *规则: 子类与父类中同名同参数的方法必须同时声明为static的(不是重写),或者同时声明为非static的(即为重写)。
	 * 
	 * 
	 * [面试题] 方法的重写与重载的区别 ?
	 * 
	 */
	public class OverrideTest {
		
		public static void main(String[] args) {
			Student s = new Student();
			s.eat();
		}
	}

5-3 四种访问权限修饰符





案例

	public class Order {
	
		private int orderPrivate;
		int orderDefault;
		protected int orderProtected;
		public int orderPublic;
	
		private void methodPrivate() {
			orderPrivate = 1;
			orderDefault = 1;
			orderProtected = 1;
			orderPublic = 1;
		}
	
		void methodDefault() {
			orderPrivate = 1;
			orderDefault = 1;
			orderProtected = 1;
			orderPublic = 1;
		}
	
		protected void methodProtected() {
			orderPrivate = 1;
			orderDefault = 1;
			orderProtected = 1;
			orderPublic = 1;
		}
	
		public void methodPublic() {
			orderPrivate = 1;
			orderDefault = 1;
			orderProtected = 1;
			orderPublic = 1;
		}
	
	}
	
	class OrderTest{
		
		public void method(){
			Order order = new Order();
			order.orderDefault = 1;
			order.orderProtected = 1;
			order.orderPublic = 1;
			
			order.methodDefault();
			order.methodProtected();
			order.methodPublic();
			
	//		order.orderPrivate = 1;
	//		order.methodPrivate();
			
			
		}
		
	}

5-4 关键字:super



案例

	public class Creature {
		
		boolean isMale;
		
	}

	public class Person extends Creature{
		
		String name;
		private int age;
		int id = 1001;//身份证号
		
		public Person() {
			System.out.println("我是Person!!");
		}
		
		public Person(String name){
			this.name = name;
		}
		
		public Person(String name, int age) {
			this.name = name;
			this.age = age;
		}
		
		public void eat(){
			System.out.println("吃饭");
		}
		
		
		
		public void walk(){
			System.out.println("走路");
		}
		
		
		
		
	}

public class Student extends Person { String major;
		int id = 1002;//学号

		public Student() {
	//		super();
			this.name = "Tom";
			super.name = "Jerry";
		}

		public Student(String major) {
			super("Tom");
			this.major = major;
		}
		
		public Student(String name,int age,String major){
	//		this.name = name;
	//		super.age = age;
			super(name,age);
			this.major = major;
			
		}


		public void eat() {
			System.out.println("学生应该多吃有营养的食物");
		}

		public void show(){
			this.name = "Tom";
			super.name = "Jerry";
			
			super.isMale = true;
			this.walk();
			super.walk();
		}
		
		public void info(){
			System.out.println(id);
			System.out.println(this.id);
			System.out.println(super.id);
			
			eat();
			this.eat();
			super.eat();
		}
	}

/** * super关键字的使用: * 1.super:理解为:父类的 * 2.super可以用来调用属性、方法、构造器 * * 3.super调用属性、方法 * 3.1 有了继承以后,我们可以在子类的方法或构造器中,通过"super.属性"或者"super.方法"的方式,显式的调用 * 父类中声明的属性或方法。但是很多情况下,我们都可以省略"super." * * 3.2 如果子类和父类中出现了同名的属性,那么我们如果在子类中调用父类中同名的属性的话,必须使用"super."的方式。 * >说明:子类的属性不会覆盖父类中同名属性。在堆空间中,两个属性都会存在。 * * 3.3 如果子类重写了父类中的方法,那么我们我们希望在子类中调用父类中被重写的方法,必须使用"super."的方式。 * * 4.super调用构造器:super(形参列表) * 4.1 在子类的构造器的首行,显示的使用“super(形参列表)”的方式,调用父类指定的构造器 * 4.2 针对于子类的某一个构造器而言,只能最多声明一个“super(形参列表)” * 4.3 在子类的构造器的首行,要么使用“this(形参列表)” ,要么使用"super(形参列表)",不能同时出现。 * 4.4 在子类构造器的首行,既没有显式的使用“this(形参列表)”,也没有显式的使用"super(形参列表)",那么默认提供 * 的是:“super()”. * 4.5 在子类的多个构造器中,至少有一个构造器的首行使用了"super(形参列表)" * */ public class SuperTest { public static void main(String[] args) { Student s = new Student();
			System.out.println();
			s.show();
			
			System.out.println();
			
			s.info();
			
			
		}

	}





5-5 子类对象实例化过程

案例

public class Creature {
	int age;
	
	public Creature(){
		super();
	}
	public Creature(int age){
		this.age = age;
	}
	
	public void breath(){
		System.out.println("呼吸");
	}
}

public class Animal extends Creature {
	String name;
	String food;
	
	public Animal(){}
	
	public Animal(String name){
		super();
		this.name = name;
	}
	public Animal(String name,String food){
		this(name);
		this.food = food;
	}
	public Animal(int age,String name,String food){
		super(age);
		this.name = name;
		this.food = food;
	}
	
}

public class Dog extends Animal {
	String hostName;
	
	public Dog(String hostName){
		this.hostName = hostName;
	}
	
	public Dog(String hostName,String name){
		super(name);
		this.hostName = hostName;
	}
	
	public Dog(String hostName,String name,String food){
		super(name, food);
		this.hostName = hostName;
	}

}

/** * 子类对象实例化的全过程: * * 1.结果上看:(继承性) * 子类在继承父类以后,就获取了所有的父类中声明的属性和方法。 * * * 2.从过程上:我们在实例化子类对象的过程中,一定会直接或间接的调用父类的构造器,以及父类的父类的构造器,。。。 * 直到调用到java.lang.Object的空参构造器为止。正因为加载了这些父类的结构,所以,我们在子类对象的内存中 * 才有所有父类中声明的属性和方法。 * * 说明:在子类对象整个实例化过程中,只创建了唯一的一个对象,即为当前的子类对象。 * */ public class InstanceTest { public static void main(String[] args) { Dog dog = new Dog("小明","花花","骨头");
		dog.breath();
		String str = dog.toString();
	}
}






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


案例

public class Creature {

}

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

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("男人西装革履,笔挺的走路");
	}

}

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("女人窈窕的走路!");
	}
	
}

/** * 面向对象的特征三:多态性的使用 * * 1.多态性:可以理解为一个事物的多种形态。 * * 2.广义上多态性的体现: * ①方法的重载 和 方法的重写 * ②子类对象的多态性 * * 3.狭义上多态性的体现:子类对象的多态性 * * 4.子类对象的多态性:父类的引用指向子类的对象。(子类的对象赋给父类的引用) * * 5.多态的应用场景:虚拟方法调用:编译时,认为调用的方法是父类的,但是当运行时,实际执行的是子类重写父类的方法 * * 说明:多态中方法的调用:编译看左边,运行看右边! * * 6.多态性,只适用于方法! * * 7.多态性使用的前提:①类的继承关系 ②方法的重写 * * */ public class PersonTest { public static void main(String[] args) {
		Person p1 = new Person();
		p1.eat();
		p1.walk();
		
		Man m1 = new Man();
		m1.eat();
		m1.walk();
		m1.earnMoney();
		
		System.out.println("**************************");
		Person p2 = new Man();//子类对象的多态性。
		//多态的应用场景:
		//虚拟方法调用:编译时,认为调用的方法是父类的,但是当运行时,实际执行的是子类重写父类的方法
		p2.eat();
		p2.walk();
		//不能通过父类的引用调用子类特有的方法
//		p2.earnMoney();
		//总结:多态中方法的调用:编译看左边,运行看右边!
		
		//总结:属性,不存在多态性的!声明的引用的类型是什么,调用的就是相应类中的属性
		System.out.println(p2.id);//1001
		
		
		System.out.println("**************************");
		
		Person p3 = new Woman();
		p3.eat();
		p3.walk();
		
//		p3.goShopping();
		
		
		System.out.println("**************************");
		//由于子类对象赋给了父类的引用,导致我们在编译时,只能调用父类中声明的结构:属性和方法。
		//但是,我们在内存结构中,又确实存在子类特有的属性和方法。那么,我们考虑如何才能调用子类所特有的属性、方法。
		//向下转型的使用:强制类型转换! 强转符:()
		Woman w1 = (Woman)p3;
		w1.goShopping();
		System.out.println(w1.isBeauty);
		
		//注意:使用强制类型转换符,可能出现ClassCastException的异常。
//		Woman w2 = (Woman)p2;
//		w2.goShopping();
		
		/*
		 * instanceof的使用:
		 * 
		 * a instanceof A : 判断对象a是否是类A的实例。如果a是类A的实例,返回true。否则,返回false.
		 * 
		 * 
		 * 如果 a instanceof A 返回true,则 a instanceof AA 返回也是true.
		 * 其中,AA是A的父类。
		 */
		
		if(p3 instanceof Woman){
			System.out.println("****1********");
			Woman w3 = (Woman)p3;
			w3.goShopping();
		}
		
		if(p2 instanceof Woman){
			System.out.println("****2********");
			Woman w4 = (Woman)p2;
			w4.goShopping();
		}
		
		
		if(p2 instanceof Object){
			System.out.println("*****3*******");
		}
		
		
		//多态使用上的几个问题:
		//问题一:编译能通过,运行不通过
//		Person p = new Person();
//		Man m = (Man)p;
//		m.eat();
//		m.earnMoney();
//		m.isSmoking = true;
		
		//问题二:编译通过,运行通过
		Creature c = new Man();
		Person p4 = (Person)c;
		p4.eat();
		
		//问题三:编译不通过
		//此时的Woman、Man;String、Date之间没有任何子父类的关系
//		Woman w = (Woman)(new Man());
//		String s = new Date();
		
		//在问题三的基础上,可以通过代码实现编译通过,但是运行仍然不通过!
//		Person p = new Man();
//		Woman w = (Woman)p;
		
	}
}




多态性的应用案例

//多态性的应用
public class AnimalTest {
	
	public static void main(String[] args) {
		AnimalTest a = new AnimalTest();
		a.func(new Dog());
		
		a.func(new Cat());
	}
	
	public void func(Animal animal){//Animal animal = new Dog()
		animal.eat();
		animal.jump();
		
		
		if(animal instanceof Dog){
			Dog dog = (Dog) animal;
			dog.shout();
		}else if(animal instanceof Cat){
			Cat cat = (Cat) animal;
			cat.catchMouse();
		}
		
		
		
		
	}
	
//	public void func(Dog dog){
//		dog.eat();
//		dog.jump();
//	}
//	
//	public void func(Cat cat){
//		cat.eat();
//		cat.jump();
//	}
}

class Animal{
	
	public void eat(){
		System.out.println("进食");
	}
	
	public void jump(){
		System.out.println("跳");
	}
	
}

class Dog extends Animal{
	
	public void eat(){
		System.out.println("狗吃骨头");
	}
	
	public void jump(){
		System.out.println("狗急跳墙");
	}
	
	public void shout(){
		System.out.println("汪汪叫");
	}
	
}

class Cat extends Animal{
	public void eat(){
		System.out.println("猫吃鱼");
	}
	
	public void jump(){
		System.out.println("猫跳着上树");
	}
	
	public void catchMouse(){
		System.out.println("猫抓老鼠");
	}
}

/*
举例二:
class Customer{
	Account acct;
	
	public void setAccount(Account acct){ //Account acct = new SavingAccount();
		this.acct = acct;
	}

}

class Account{

}

class CheckAccount extends Account{//信用卡账户

}

class SavingAccoujnt extends Account{//储蓄卡账户

}

举例三:数据库连接


class Driver{
	
	public void do(Connection conn){//Connection conn = mysql的Connection的子类
		//规范化的连接和增删改查操作。
	}

}
 */



练习

/*
 * 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中
 *  对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量
 *  
 */
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;
		System.out.println(b == s);//true
		System.out.println(b.count);//10
		b.display();//20
	}
}
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);
	}
}





练习

/*
 * 
 * 建立InstanceTest 类,在类中定义方法method1(Person e);
在method1中:
(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 IntanceTest {
	public static void main(String[] args) {
		IntanceTest test = new IntanceTest();
		Person e = new Graduate();
		e = new Student();
		test.method1(e);
	}
	
	public void method1(Person e){//Person e = new Graduate();
		
		String info = e.getInfo();
		System.out.println(info);
		
		
		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;
	}
}




5-7 Object类的使用



案例

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;
	}
	
	//自动生成的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;
	}
	
	//手动重写的:重写Object类中的equals()
//	public boolean equals(Object obj) {
//		
//		if(this == obj){
//			return true;
//		}
//		
//		if(obj instanceof Customer){
//			
//			Customer c = (Customer)obj;
//			
//			return this.name.equals(c.name) && this.age == c.age; 
//			
//		}
//		
//		return false;
//		
//	}
	
	//手动重写的toString():
//	@Override
//	public String toString() {
//		return "Customer[name = " + name + ",age = " + age + "]" ;
//	}
	//自动生成toString():
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}
	
}

import java.util.Date;
/**
 * equals()方法的使用
 * 
 * 1.java.lang.Object类中的equals()方法的定义:
 *   
 *   public boolean equals(Object obj) {
		return (this == obj);
	 }
 * 
 *   说明:Object类中equals()比较两个对象的引用地址是否相同。(或:比较两个引用是否指向同一个对象实体)
 * 
 *  2. 像String、Date、File、包装类等重写了Object类中的equals()方法,比较两个对象中的实体内容是否相等。
 *  
 *  3. 对于自定义类来讲,如果没有重写Object类中的equals()方法,调用equals()方法时,仍然比较两个对象的引用地址
 *  是否相同。
 *     
 *  4. 一般情况下,在开发中一旦调用了自定义类的equals(),通常都是重写以后的equals()方法。
 *  
 *  5.重写equals()的规则:比较两个对象的属性是否都相等。
 * 
 * 
 *  面试题:== 和 equals() 区别?
 *    
 *    ==:使用范围:可以操作基本数据类型  和  引用数据类型
 *       如果操作的是基本数据类型:比较两个基本数据类型的变量对应的值是否相等。
 *       如果操作的是引用数据类型:比较两个引用的地址是否相同。
 *    
 *    
 *    equals():使用范围:只适用于引用数据类型
 *  		      具体的使用:见上面的1-5
 *  
 *
 */
public class EqualsTest {
	public static void main(String[] args) {
		String str1 = new String("zhangsan");
		String str2 = new String("zhangsan");
		
		System.out.println(str1 == str2);//false
		
		System.out.println(str1.equals(str2));//true
		
		Date date1 = new Date(12141412L);
		Date date2 = new Date(12141412L);
		
		System.out.println(date1.equals(date2));//true
		
		
		Customer c1 = new Customer("Tom", 12);
		Customer c2 = new Customer("Tom", 12);
		
		System.out.println(c1.equals(c2));//false--->true
		
		System.out.println(c1 == c2);//false
		
		int[] arr1 = new int[]{1,2,3};
		int[] arr2 = new int[]{1,2,3};
		System.out.println(arr1.equals(arr2));
		System.out.println(arr1.equals(arr1));
		
		System.out.println("*************************");
		
		// == 
		int num1 = 10;
		int num2 = 10;
		System.out.println(num1 == num2);//true
		double d1 = 10.0;
		System.out.println(num1 == d1);//true
		
		char c = 10;
		System.out.println(num1 == c);//true
		
		char cc = 'A';
		int num = 65;
		System.out.println(cc == num);//true
		
//		System.out.println(true == num);//编译不通过
		
//		System.out.println("hello" == new java.util.Date()); //编译不通过
		
		
	}
}




练习

Peson p1 = new Person();
p1.name = "zhangsan";
Peson p2 = new Person();
p2.name = "zhangsan";
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
System.out.println(p1.name=="zhangsan");//true

String str1 = new String("zhangsan");
String str2 = new String("zhangsan");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true



练习1

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

 */
public class Order {
	private int orderId;
	private String orderName;
	
	public Order(int orderId, String orderName) {
		super();
		this.orderId = orderId;
		this.orderName = 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;
	}
	
	@Override
	public boolean equals(Object obj) {
		
		if(this == obj){
			return true;
		}
		
		if(obj instanceof Order){
			Order o = (Order)obj;
			
			return this.orderId == o.orderId && this.orderName.equals(o.orderName);
		}
		
		return false;
		

	}
	
}

public class OrderTest { public static void main(String[] args) { Order o1 = new Order(1001, new String("order_A")); Order o2 = new Order(1001, new String( "order_A"));
		System.out.println(o1.equals(o2));
	}
}

练习2
/*
 *  equals()课后练习2:
 * 请根据以下代码自行定义能满足需要的MyDate类,在MyDate类中覆盖equals方法,
 * 使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。  
 *   public boolean equals(Object o)

 */
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;
	}



	@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;
	}
	
	
//	@Override
//	public boolean equals(Object obj) {
//		
//		if(this == obj){
//			return true;
//		}
//		
//		if(obj instanceof MyDate){
//			
//			MyDate m = (MyDate)obj;
//			return this.year == m.year && this.month == m.month && this.day == m.day;
//			
//		}
//		
//		return false;
//	}
//	
}

class EqualsTest {
	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");
		}
	}
}


案例

import java.util.Date;

/**
 *  toString()的使用:
 * 
 * 1.java.lang.Object类中toString()定义如下:
 *  public String toString() {
		return getClass().getName() + "@" + Integer.toHexString(hashCode());
	}
 * 
 * 2. 当我们打印一个对象的引用时,实际上就是调用了其toString()
 * 
 * 3. 像String、Date、File、包装类等重写了Object类中的toString(),返回其代表的具体内容
 * 
 * 4. 对于自定义类而言,如果我们没有重写Object类中的toString()方法,则返回的仍然是地址值。
 *     如果重写的话,重写的规则:返回当前对象的属性信息。
 * 
 *
 */
public class ToStringTest {
	public static void main(String[] args) {
		
		Customer c = new Customer("Tom", 12);
		System.out.println(c.toString());//com.tzy.java.Customer@15db9742-->Customer[name = Tom,age = 12]
		System.out.println(c);//com.tzy.java.Customer@15db9742 -->Customer[name = Tom,age = 12]
		
		String s = new String("北京天安门");
		System.out.println(s);
		System.out.println(s.toString());
		
		Date d =  new Date();
		System.out.println(d.toString());
		
		
	}
}


答案: abc 地址 地址


练习

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

}

public class Circle extends GeometricObject {
	private double radius;
	
	public Circle(){
		super();
		this.radius = 1.0;
//		this.color = "white";
//		this.weight = 1.0;
	}
	
	public Circle(double radius){
//		this.color = "white";
//		this.weight = 1.0;
		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;
	}
	
	@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 +"]";
	}
}

public class CircleTest { public static void main(String[] args) { Circle c1 = new Circle(2.3); Circle c2 = new Circle(2.3, "white", 2.0);
		System.out.println("c1 与 c2的颜色是否相同:" + (c1.getColor().equals(c2.getColor())));
		
		System.out.println("c1 与 c2的半径是否相同:" + c1.equals(c2));
		
		System.out.println("c1的半径为:" + c1.toString());
		
	}
}

5-8 单元测试

首先装入JUnitGenerator 插件

这样可以在alt+ins快捷键时生成我们的junit测试类

然后需要导包 junit-4.10.jar

案例

public class JUnitTest {
	
	int num = 1;
	
	@Test
	public void testMethod1(){
		System.out.println("hello!");
		System.out.println(num);
		
		int num2 = getNum(10);
		System.out.println(num2);
	}
	
	public int getNum(int n){
		return n;
	}
	
	@Test
	public void testMethod2(){
		System.out.println("hellobejing!");
		
		Object obj = new String("ABC");
		Date d = (Date)obj;
	}
}

5-9 包装类的使用





案例

public class WrapperTest {
	
	//String类--->基本数据类型、包装类:调用包装类Xxx的parseXxx()
	@Test
	public void test5(){
		String s1 = "123";
//		int num1 = (int)s1;
//		int num2 = (Integer)s1;
		
		int num3 = Integer.parseInt(s1);
		System.out.println(num3 + 1);
	}
	
	//基本数据类型、包装类---->String类:调用String的重载的方法:valueOf(xxx x)
	@Test
	public void test4(){
		int num1 = 123;
		Integer i1 = 123;
		//方式1:
		String s1 = num1 + "";
		String s2 = i1 + "";
		
		System.out.println(s1);//"123"
		System.out.println(s2);//"123"
		//方式2:
		String s3 = String.valueOf(num1);
		System.out.println(s3);
	}
	
	//jdk 5.0 新特性:自动装箱 与 自动拆箱
	@Test
	public void test3(){
		int num1 = 10;
		Integer i1 = num1;//自动装箱
		System.out.println(i1.toString());
		
		int num2 = i1;//自动拆箱
		System.out.println(num2);
		
		
		method(num1);
	}
	
	
	public void method(Object i){//public void method(Integer i){
		System.out.println("***********" + i);
	}
	
	
	//包装类---->对应的基本数据类型:调用包装类Xxx的xxxValue()
	@Test
	public void test2(){
		Integer i1 = new Integer(123);
		int num = i1.intValue();
		System.out.println(num);
		
		Boolean b = new Boolean(true);
		boolean b1 = b.booleanValue();
		System.out.println(b1);
		
	}
	
	//基本数据类型---->对应的包装类:调用包装类的构造器
	@Test
	public void test1(){
		int num1 = 10;
		//Integer:
//		System.out.println(num1.toString());
		Integer i1 = new Integer(num1);
		i1 = new Integer("123");
		System.out.println(i1.toString());
		
		//Float:
		Float f1 = new Float(123.3F);
		f1 = new Float("12.3F");
		System.out.println(f1);
		
		//注意:使用String参数的构造器,要小心出现:NumberFormatException的异常
//		Integer i2 = new Integer("123a");
//		System.out.println(i2);
		
		
		//Boolean:
		Boolean b1 = new Boolean(true);
		System.out.println(b1);
		
		b1 = new Boolean("TRue");
		System.out.println(b1);
		//只要形参的字符串,在忽略大小写的情况下不是"true",那么都返回false.
		b1 = new Boolean("true123");
		System.out.println(b1);
		
		System.out.println();
		AA a = new AA();
		System.out.println(a.isFlag);//false--->null
		
	}
}

class AA{
//	boolean isFlag;//只能取值为true / false
	Boolean isFlag;//默认取值为null
}


答案

1题 1.0

2题1

答案

1题 false

2题 true

3题 false

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

/*
 * 利用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 ScoreTest {
	public static void main(String[] args) {
		//1.Scanner的实例化,用户从键盘获取学生成绩
		Scanner scanner = new Scanner(System.in);
		//2.通过for(;;),多次从键盘获取学生成绩。
		//3.实例化Vector:Vector v=new Vector();
		//5.获取学生成绩的最大值:maxScore。
		//5.1 声明
		int maxScore = 0;
		Vector vector = new Vector();
		for(;;){
			System.out.println("请输入学生的成绩:(以负数代表输入结束)");
			int score = scanner.nextInt();
			if(score < 0){
				//循环终止条件:以负数代表输入结束
				break;
			}else if(score > 100){
				System.out.println("输入的成绩非法,请重新输入");
			}else{
				//JDK5.0之前:
//				Integer i = new Integer(score);
//				vector.addElement(i);
				//JDK5.0及之后:
				//4.调用相关方法,将学生成绩保存在Vector的实例中。
				vector.addElement(score);//自动装箱
				//5.2 获取最高分
				if(maxScore < score){
					maxScore = score;
				}
			}
		}
		
		//6.遍历获取每个学生成绩,并输出其等级。
		char grade ;
		for(int i = 0;i < vector.size();i++){
			//JDK5.0之前:
//			Object obj = vector.get(i);
//			Integer scoreValue = (Integer)obj;
//			int score = scoreValue.intValue();
			//JDK5.0及之后:
			int score = (int) vector.get(i);
			
			if(maxScore - score <= 10){
				grade = 'A';
			}else if(maxScore - score <= 20){
				grade = 'B';
			}else if(maxScore - score <= 30){
				grade = 'C';
			}else{
				grade = 'D';
			}
			System.out.println("学生" + (i + 1) + "的成绩为:" + score + ",等级为:" + grade);
		}
	}
}

posted on 2018-09-20 17:49  咘雷扎克  阅读(266)  评论(0编辑  收藏  举报

导航