Java學習路線:day13 面向對象(中)2

全部源碼:https://github.com/name365/JavaSE-30Day

轉載自atguigu.com視頻

第四章 面向對象(中)

面向對象特徵之三:多態性

向下轉型的使用

  • Person 類
public class Person {
	String name;
	int age;
	
	public void eat(){
		System.out.println("人,喫飯");
	}
	
	public void walk(){
		System.out.println("人,走路");
	}
	
}
  • Man 類
public class Man extends Person{
	
	boolean isSmoking;
	
	public void earnMoney(){
		System.out.println("男人負責工作養家");
	}
	
	public void eat() {
		System.out.println("男人多喫肉,長肌肉");
	}
	
	public void walk() {
		System.out.println("男人霸氣的走路");
	}
}
  • Woman 類
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 類
/*
 * 面向對象之三:多態性
 * 
 * 1.理解多態性:可以理解爲一個事物的多種態性。
 * 2.何爲多態性:
 * 	 對象的多態性:父類的引用指向子類的對象(或子類的對象賦值給父類的引用)
 * 
 * 3.多態的使用:虛擬方法調用
 * 	有了對象多態性以後,我們在編譯期,只能調用父類聲明的方法,但在執行期實際執行的是子類重寫父類的方法
 * 			簡稱:編譯時,看左邊;運行時,看右邊。
 *  
 *  若編譯時類型和運行時類型不一致,就出現了對象的多態性(Polymorphism)
 *  多態情況下,
 *  	“看左邊”:看的是父類的引用(父類中不具備子類特有的方法)
 *  	“看右邊”:看的是子類的對象(實際運行的是子類重寫父類的方法)
 *  
 *  4.多態性的使用前提:
 *  	① 類的繼承關係
 *  	② 方法的重寫
 *  5.對象的多態性:只適用於方法,不適用於屬性(編譯和運行都看左邊)
 */
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是Person類型,

		// p2.earnMoney();

		p2.name = "Tom";
		// p2.isSmoking = true;
		// 有了對象的多態性以後,內存中實際上是加載了子類特有的屬性和方法,但是由於變量聲明爲父類類型,導致
		// 編譯時,只能調用父類中聲明的屬性和方法。子類的屬性和方法不能調用。

		// 如何才能調用子類所特有的屬性和方法?
		// 使用強制類型轉換符,也可稱爲:向下轉型
		Man m1 = (Man) p2;
		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************");
		}
		
		//向下轉型的常見問題
		//練習
		//問題1:編譯時通過,運行時不通過
		//舉例一
//		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;
	}
}

在這裏插入圖片描述

多態性的練習

  • 練習1
/*
 * 練習:子類繼承父類
 * 
 * 1.若子類重寫了父類方法,就意味着子類裏定義的方法徹底覆蓋了父類裏的同名方法,
 * 系統將不可能把父類裏的方法轉移到子類中。
 * 
 * 2.對於實例變量則不存在這樣的現象,即使子類裏定義了與父類完全相同的實例變量,
 * 這個實例變量依然不可能覆蓋父類中定義的實例變量
 * 
 */
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();
	}
}

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);
	}
}
  • 練習2
/*
 * 建立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”
 * 
 */
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;
	}
}


public class InstanceTest{
	
	public static void main(String[] args) {
		//虛擬方法調用
		InstanceTest test = new InstanceTest();
		test.method(new Student());
		
	}
	
	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");
		}
	}
}
  • 練習3
  • GeometricObject類
/*
 * 定義三個類,父類GeometricObject代表幾何形狀,子類Circle代表圓形,MyRectangle代表矩形。
 */
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;
	}
}
  • Circle類
public class Circle extends GeometricObject {

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

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	@Override
	public double findArea() {
		return 3.14 * radius * radius;
	}
}
  • MyRectangle類
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.height = height;
		this.width = width;
	}

	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;
	}
}
  • GeometricTest類
/*
 * 定義一個測試類GeometricTest,編寫equalsArea方法測試兩個對象的面積是否相等(注意方法的參數類型,利用動態綁定技術),
 * 編寫displayGeometricObject方法顯示對象的面積(注意方法的參數類型,利用動態綁定技術)。
 * 
 */
public class GeometricTest {
	
	public static void main(String[] args) {
		GeometricTest test = new GeometricTest();
		
		Circle c1 = new Circle(2.3,"white",1.0);
		test.displayGeometricObject(c1);
		
		Circle c2 = new Circle(3.3,"white",1.0);
		test.displayGeometricObject(c2);
		
		boolean isEqual = test.equalsArea(c1, c2);
		System.out.println("面積是否相等: " + isEqual);
		
		MyRectangle rect = new MyRectangle(2.1, 3.4,"red",1.0);
		test.displayGeometricObject(rect);
	}
	
	public void displayGeometricObject(GeometricObject o){
		System.out.println("面積爲: " + o.findArea());
	}
	
	//測試兩個對象的面積是否相等
	public boolean equalsArea(GeometricObject o1,GeometricObject o2){
		return o1.findArea() == o2.findArea();
	}
}
  • 練習4
/*
 * 面試題:多態是編譯時行爲還是運行時行爲?如何證明?
 * 
 * 證明見如下:
 */
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();
		 
	}
}
  • 面試題拓展
/* 考查多態的筆試題目:
 * 面試題:多態是編譯時行爲還是運行時行爲?如何證明?
 * 
 * 拓展問題
 */
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 類的使用

/*
 * 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的區別?
 * 
 */
public class ObjectTest {

	public static void main(String[] args) {
		
	}
}

class Order{
	
}

Object類中的主要結構

在這裏插入圖片描述

==操作符與equals方法

import java.sql.Date;

/*
 * 面試題: ==和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;
		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("BAT");
		String str2 = new String("BAT");
		System.out.println(str1 == str2); //false
		System.out.println("*************************");
		System.out.println(cust1.equals(cust2));	//false
		System.out.println(str1.equals(str2));	//true
		
		Date date1 = new Date(23432525324L);
		Date date2 = new Date(23432525324L);
		System.out.println(date1.equals(date2));	//true
	}
}
  • Customer類
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);
//		}
//		
//		return false;
//	}
		
}

重寫equals()方法的原則

  • 對稱性:如果x.equals(y)返回是“true”,那麼y.equals(x)也應該返回是“true”。
  • 自反性:x.equals(x)必須返回是“true”。
  • 傳遞性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那麼z.equals(x)也應該返回是“true”。
  • 一致性:如果x.equals(y)返回是“true”,只要x和y內容一直不變,不管你重複x.equals(y)多少次,返回都是“true”。
  • 任何情況下,x.equals(null),永遠返回是“false”;x.equals(和x不同類型的對象)永遠返回是“false”。
	int it = 65;
    float fl= 65.0f;
	System.out.println("65和65.0f是否相等?" + (it == fl)); //true
	char ch1 = 'A'; 
	char ch2 = 12;
	System.out.println("65和'A'是否相等?" + (it == ch1));//true
	System.out.println("12和ch2是否相等?" + (12 == ch2));//true 
	String str1 = new String("hello");
	String str2 = new String("hello");
	System.out.println("str1和str2是否相等?"+ (str1 == str2));//false
	System.out.println("str1是否equals str2?"+(str1.equals(str2)));//true
	System.out.println("hello" == new java.util.Date()); //編譯不通過
  • 練習一
/*
 * .編寫Order類,有int型的orderId,String型的orderName,
 * 相應的getter()和setter()方法,兩個參數的構造器,重寫父類的equals()方法:public booleanequals(Object obj),
 * 並判斷測試類中創建的兩個對象是否相等。
 * 
 * 
 */
public class OrderTest {
	public static void main(String[] args) {
		Order order1 = new Order(1001,"AA");
		Order order2 = new Order(1001,"BB");
		
		System.out.println(order1.equals(order2));	//false
		
		Order order3 = new Order(1001,"BB");
		System.out.println(order2.equals(order3)); //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;
	}
	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;
	}
}
  • 練習二
/*
 * 請根據以下代碼自行定義能滿足需要的MyDate類,在MyDate類中覆蓋equals方法,
 * 使其判斷當兩個MyDate類型對象的年月日都相同時,結果爲true,否則爲false。
 * public boolean equals(Object o)
 */
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的使用

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);
//		}
//		
//		return false;
//	}
	
	//手動實現
//	@Override
//	public String toString() {
//		return "Customer[name = " + name + ",age = " + age + "]";
//	}
	
	//自動實現
	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}

}
  • ToStringTest類
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 ToStringTest {
	public static void main(String[] args) {
		
		Customer cust1 = new Customer("Tom" ,21);
		System.out.println(cust1.toString());	//github4.Customer@15db9742
		System.out.println(cust1); 	//github4.Customer@15db9742 ---> Customer[name = Tom,age = 21]
		
		String str = new String("MM");
		System.out.println(str);
		
		Date date = new Date(45362348664663L);
		System.out.println(date.toString());	//Wed Jun 24 12:24:24 CST 3407
		
	}
}
  • 練習
  • GeometricObject類
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;
	}
}
  • Circle類
public class Circle extends GeometricObject{
	private double radius;

	public Circle() {	//初始化對象的color屬性爲“white”,weight屬性爲1.0,radius屬性爲1.0。
		super();	//super自帶,不需再寫
//		this.color = "white";
//		this.weight = 1.0;
		this.radius = 1.0;
	}

	//初始化對象的color屬性爲“white”,weight屬性爲1.0,radius根據參數構造器確定。
	public Circle(double radius) {	
		super();	//super自帶,不需再寫
//		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 Math.PI * radius * radius;
	}
	
	@Override	//重寫equals方法,比較兩個圓的半徑是否相等,如相等,返回true。
	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() {	//重寫toString方法,輸出圓的半徑。
		return "Circle [radius=" + radius + "]";
	}
	
}
  • 測試類
/*
 * 寫一個測試類,創建兩個Circle對象,判斷其顏色是否相等;
 * 利用equals方法判斷其半徑是否相等;利用toString()方法輸出其半徑。
 * 
 */
public class CircleTest {
	public static void main(String[] args) {
		
		Circle circle1 = new Circle(2.3);
		Circle circle2 = new Circle(3.3,"white",2.0);
		
		System.out.println("顏色是否相等: " + circle1.getColor().equals(circle2.color));
		
		System.out.println("半徑是否相等: " + circle1.equals(circle2));
		
		System.out.println(circle1);
		System.out.println(circle2.toString());
	}
}

包裝類(Wrapper)的使用

單元測試方法的使用

import java.util.Date;
import org.junit.Test;
/*
 * java中的JUnit單元測試
 * 
 * 步驟:
 * 1.選中當前項目工程 --》 右鍵:build path --》 add libraries --》 JUnit 4 --》 下一步
 * 2.創建一個Java類進行單元測試。
 * 	 此時的Java類要求:①此類是公共的 ②此類提供一個公共的無參構造器 
 * 3.此類中聲明單元測試方法。
 *   此時的單元測試方法:方法的權限是public,沒有返回值,沒有形參。
 * 
 * 4.此單元測試方法上需要聲明註解:@Test並在單元測試類中調用:import org.junit.Test;
 * 5.聲明好單元測試方法以後,就可以在方法體內測試代碼。
 * 6.寫好代碼後,左鍵雙擊單元測試方法名:右鍵 --》 run as --》 JUnit Test
 * 
 * 說明:如果執行結果無錯誤,則顯示是一個綠色進度條,反之,錯誤即爲紅色進度條。
 */
public class JUnit {
	
	int num = 10;
	
	//第一個單元測試方法
	@Test
	public void testEquals(){
		String s1 = "MM";
		String s2 = "MM";
		System.out.println(s1.equals(s2));
		
		//ClassCastException的異常
//		Object obj = new String("GG");
//		Date date = (Date)obj;
		
		System.out.println(num);
		show();
	}
	
	public void show(){
		num = 20;
		System.out.println("show()...");
	}
	
	//第二個單元測試方法
	@Test
	public void testToString(){
		String s2 = "MM";
		System.out.println(s2.toString());
	}
}

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

包裝類的使用

/*
 * 包裝類的使用
 * 1.java提供了8種基本數據類型對應的包裝類,使得基本數據類型的變量具有類的特徵
 * 		基本數據類型		包裝類
 * 		byte			Byte
 * 		short			Short
 * 		int 			Integer
 * 		long			Long
 * 		float			Float
 * 		double			Double
 * 		boolean			Boolean
 * 		char			Character
 * 注意:其中Byte、Short、Integer、Long、Float、Double的父類是:Number
 * /

包裝類與基本數據類型相互轉換

在這裏插入圖片描述

import org.junit.Test;
/*
 * 2.基本數據類型、包裝類、String三者之間的相互轉換。
 * 
 */
public class WrapperTest {
	
	//String類型---> 基本數據類型、包裝類,調用包裝類的parseXxx()
	@Test
	public void test5(){
		String str1 = "123";
//		String str1 = "123a";
		
		//錯誤的情況,可能會報錯
//		int num1 = (int)str1;
//		Integer in1 = (Integer)str1;
		
		int num2 = Integer.parseInt(str1); 
		System.out.println(num2 + 1);	//124
		
		String str2 = "true";
		Boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);	//true
		
	}
	
	//基本數據類型、包裝類---》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"
		
	}
	
	/*
	 * JDK 5.0 新特性:自動裝箱與自動拆箱
	 */
	@Test
	public void test3(){
//		int num1 = 10;
//		//基本數據類型 --》 包裝類的對象
//		method(num1);	//Object obj = num1
		
		//自動裝箱:基本數據類型 --》 包裝類
		int num2 = 10;
		Integer in1 = num2;//自動裝箱
		
		boolean b1 = true;
		Boolean b2 = b1;//自動裝箱
		
		//自動拆箱:包裝類 --》 基本數據類型
		System.out.println(in1.toString());
		
		int num3 = in1;
		
	}
	
	public void method(Object obj){
		System.out.println(obj);
	}
	
	//包裝類 --》 基本數據類型:調用包裝類的xxxValue()
	@Test
	public void test2() {
		Integer in1 = new Integer(12);
		int i1 = in1.intValue();
		System.out.println(i1 + 1); 
		
		Float f1 = new Float(12.3f);
		float f2 = f1.floatValue();
		System.out.println(f2 + 1); 
	}
	
	//基本數據類型--》包裝類,調用包裝類的構造器
	@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 b1 = new Boolean(true);
		Boolean b2 = new Boolean("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 isFemale;
}

練習

  • 面試題
import org.junit.Test;
/*
 * 如下兩個題目輸出結果相同嗎?各是什麼:
 * 		Object o1= true? new Integer(1) : new Double(2.0);
 * 		System.out.println(o1);//
 * 
 * 		Object o2;
 * 		if(true)
 * 			o2 = new Integer(1);
 *		else 
 *			o2 = new Double(2.0);
 *		System.out.println(o2);//
 *
 */
public class InterViewTest {

	@Test
	public void test(){
		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 method1() {
		Integer i = new Integer(1);
		Integer j = new Integer(1);
		System.out.println(i == j); //false
		
	    //Integer內部定義了一個IntegerCache結構,IntegerCache中定義Integer[]
		//保存了從-128-127範圍的整數。如果我們使用自動裝箱的方式,給Integer賦值的範圍在其中時,
		//可以直接使用數組中的元素,不用再去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

	}
}
  • 編程題
    在這裏插入圖片描述
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 VectorTest {
	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);

		}
	}
}

整個Java全棧系列都是筆者自己敲的筆記。寫作不易,如果可以,點個讚唄!✌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章