7月16號(hào)筆記
今天的主要內(nèi)容:
- 對(duì)象和類的學(xué)習(xí)——聯(lián)系類的構(gòu)造技巧
- 數(shù)組學(xué)習(xí)——for-each
- LocalDate的學(xué)習(xí)
- 關(guān)鍵字的學(xué)習(xí)——final/static/this
- 工廠方法的學(xué)習(xí)【重點(diǎn)】
- 類的設(shè)計(jì)技巧
1. 數(shù)組的學(xué)習(xí)
-
數(shù)組定義:
int[] arr = new int[]{1,3,5,8,9,11};
-
java.util.Arrays類的使用
Arrays.toString(type[] a);
Arrays.copyOf(type[] a,int length);
Arrays.sort(type[] a);
TestArray
import java.util.Arrays;
public class TestArray{
public static void main(String[] args){
//數(shù)組的定義:
int[] arr = new int[]{1,3,5,8,9,11};
//Arrays.toString(type[] a);
String arrString = Arrays.toString(arr);
System.out.println("arr : " + arrString);
//Arrays.copyOf(type[] a,int length);
int[] b = Arrays.copyOf(arr,arr.length);
//Arrays.sort(type[] a)
Arrays.sort(b);
//for-each遍歷數(shù)組
System.out.print("After sort : ");
for(int element:b){
System.out.print(element + " ");
}
System.out.println("\n");
}
}
/*
在JDK1.8中輸出結(jié)果為:
-------------------------------
arr : [1, 3, 5, 8, 9, 11]
After sort : 1 3 5 8 9 11
-------------------------------
*/
2. java.time.LocalDate類
import java.time.LocalDate;
public class TestLocalDate{
public static void main(String[] args){
//LocalDate date1 = new LocalDate(); 不正確
//此時(shí)用靜態(tài)工廠方法代表調(diào)用的構(gòu)造器
LocalDate date = LocalDate.now();
System.out.println("The LocalDate : " + date);
LocalDate date2 = LocalDate.of(2018,7,16);
System.out.println("The LocalDate : " + date2);
//LocalDate類中的方法學(xué)習(xí)
int dayOfYear = date.getDayOfYear();
int dayOfMonth = date.getDayOfMonth();
int month = date.getMonthValue();
int year = date.getYear();
System.out.println("getDayOfYear() : " + dayOfYear
+ "\ngetDayOfMonth() : " + dayOfMonth
+ "\ngetMonthValue() : " + month
+ "\ngetYear() : " + year);
}
}
/*
在JDK1.8中輸出結(jié)果為:
------------------------------------
The LocalDate : 2018-07-16
The LocalDate : 2018-07-16
getDayOfYear() : 197 //按照陰歷計(jì)算
getDayOfMonth() : 16
getMonthValue() : 7
getYear() : 2018
------------------------------------
*/
3. 對(duì)象和類的理解
-
Employee類
-
data field:
- name,salary,hireDay
-
method:
- getName();
- getSalary();
- gethireDay();
-
class Employee
import java.time.LocalDate; class Employee{ //data field private String name; private double salary; private LocalDate hireDay; //constructor public Employee(String name,double salary,int year,int month,int day){ this.name = name; this.salary = salary; this.hireDay = LocalDate.of(year,month,day); } //method public String getName(){ return name; } public double getSalary(){ return salary; } public LocalDate gethireDay(){ return hireDay; } public void raiseSalary(double byPercent){ salary += salary * byPercent/100; } }
-
-
EmployeeTest類
public class EmployeeTest{ public static void main(String[] args){ Employee[] staff = new Employee[3]; staff[0] = new Employee("zhangsan",100,2018,7,9); staff[1] = new Employee("lisi",200,2018,7,16); staff[2] = new Employee("hahaha",300,2018,7,23); System.out.println("=====================所有員工信息======================"); //raise everyone's salary by 5% for(Employee e : staff){ e.raiseSalary(5); } //輸出所有員工信息 for(Employee e : staff){ System.out.println("name : " + e.getName() + " salary : " + e.getSalary() + " hiredate : " + e.gethireDay() ); } } } /* 在JDK1.8中輸出結(jié)果為: --------------------------------------------------------- =====================所有員工信息====================== name : zhangsan salary : 105.0 hiredate : 2018-07-09 name : lisi salary : 210.0 hiredate : 2018-07-16 name : hahaha salary : 315.0 hiredate : 2018-07-23 --------------------------------------------------------- */
4. 關(guān)鍵字的學(xué)習(xí)
-
final
- final修飾實(shí)例域(data field)時(shí)
- 確保在每一個(gè)構(gòu)造器執(zhí)行后,這個(gè)域的值被設(shè)置
- 在后面操作中辩蛋,不能夠再對(duì)它進(jìn)行修改
- 例如在Employee類中name域聲明為final
class Employee{ private final String name; .... }
- final關(guān)鍵字只是表示對(duì)象的引用不會(huì)再指示其他對(duì)象
- final修飾實(shí)例域(data field)時(shí)
-
static
- static修飾實(shí)例域時(shí),每個(gè)類中只有一個(gè)這樣的域
-
給每一個(gè)雇員一個(gè)標(biāo)識(shí)碼
class Employee{ private static nextID; private int id; }
此時(shí)這個(gè)類的所有實(shí)例共享nextID域,靜態(tài)域?qū)儆陬悾粚儆谌魏为?dú)立的對(duì)象
-
- static修飾實(shí)例域時(shí),每個(gè)類中只有一個(gè)這樣的域
* static修飾靜態(tài)常量時(shí)嗦锐,例如:
public class Math{
public static final double PI = 3.141592653.....;
}
* 此時(shí)可通過(guò)類名直接使用PI常量:Math.PI;
* static修飾方法時(shí)沉御,表示靜態(tài)方法是一種不能向?qū)ο髮?shí)施操作的方法
* 靜態(tài)方法不可以訪問(wèn)非靜態(tài)的
* 非靜態(tài)的可以訪問(wèn)靜態(tài)的
-
this
-
this指示隱士參數(shù),也就是所構(gòu)造的對(duì)象
public Employee(String name,double salary){ this.name = name; this.salary = salary; }
- this指的是當(dāng)前對(duì)象
this調(diào)用另一個(gè)構(gòu)造器
public Employee(double s){
//calls Employee(String,double)
this("Employee #" + nextID.s);
nextID++;
}
-
5. 工廠方法的學(xué)習(xí)
-
使用場(chǎng)景
- 在任何需要生成復(fù)雜對(duì)象的地方晾腔,可以直接new的不需要工廠模式舌稀,也就是,當(dāng)使用構(gòu)造器無(wú)法改變所構(gòu)造的類型時(shí)灼擂。
- 需要生成的對(duì)象叫做產(chǎn)品壁查,生成對(duì)象的地方叫做工廠。
-
例1:吃水果時(shí)需要區(qū)分不同水果類————課堂例子
-
創(chuàng)建Fruit接口剔应,定義水果eat規(guī)范
interface Fruit{ public void eat(); }
-
創(chuàng)建Apple和Orange兩類睡腿,繼承接口,實(shí)現(xiàn)抽象方法eat
class Apple implements Fruit{ public void eat(){ System.out.println("吃蘋果"); } } class Orange implements Fruit{ public void eat(){ System.out.println("吃橘子"); } }
-
創(chuàng)建工廠峻贮,生產(chǎn)兩產(chǎn)品
class Factory{ public static Fruit getFruit(String name){ if(name.equals("apple")){ return new Apple(); } else if(name.equals("orange")){ return new Orange(); } else{ return null; } } }
-
測(cè)試工廠類
public class Test{ public static void main(String[] args){ Factory.getFruit(args[0]).eat(); } } /* 此時(shí)程序不嚴(yán)謹(jǐn)席怪,當(dāng)輸入的參數(shù)不是apple和orange時(shí)拋出java.lang.NullPointerException */
- 此時(shí)的工廠可做到需要什么取什么,而我們不需要知道內(nèi)在如何完成纤控。
-
5.1 系統(tǒng)學(xué)習(xí)工廠模式
一. 簡(jiǎn)單(靜態(tài))工廠
一個(gè)例子:
喜歡吃水果挂捻,此時(shí)抽象一個(gè)水果類或者接口,此時(shí)這就是產(chǎn)品的抽象類
abstract class Fruit{
/*
描述說(shuō)過(guò)什么樣船万,有多好吃
*/
public abstract void desc();
}
先嘗嘗蘋果(具體的產(chǎn)品類)
class AppleFruit extends Fruit{
@Override
public void desc(){
System.out.println("蘋果好吃還便宜刻撒,嘻嘻嘻");
}
}
再試試橘子(具體的產(chǎn)品類)
class OrangeFruit extends Fruit{
@Override
public void desc(){
System.out.println("橘子好久沒吃了,有點(diǎn)酸");
}
}
還有我最愛吃的榴蓮(具體的產(chǎn)品類)
class DurianFruit extends Fruit{
@Override
public void desc(){
System.out.println("榴蓮我覺得很好吃啊");
}
}
準(zhǔn)備工作做完了耿导,我們來(lái)到一家“簡(jiǎn)單水果店”(簡(jiǎn)單工廠類)声怔,菜單如下:
class SimpleFruitFactory{
public static final int TYPE_APPLE = 1; //蘋果
public static final int TYPE_ORANGE = 2; //橘子
public static final int TYPE_DURIAN = 3; //榴蓮
public static Fruit createFruit(int type){
switch(type){
case TYPE_APPLE:
return new AppleFruit();
case TYPE_ORANGE:
return new OrangeFruit();
case TYPE_DURIAN:
return new DurianFruit();
}
}
}
簡(jiǎn)單的水果店就提供三種水果(產(chǎn)品),你說(shuō)你要啥舱呻,他就給你啥醋火。這里我買了一個(gè)榴蓮:
/*
簡(jiǎn)單工廠模式
*/
public class Test{
public static void main(String[] args){
Fruit fruit = SimpleFruitFactory.createFruit(SimpleFruitFactory.TYPE_DURIAN);
fruit.desc();
}
}
在JDK1.8中輸出結(jié)果為:
------------------
榴蓮我覺得很好吃啊
-------------------
簡(jiǎn)單(靜態(tài))工廠特點(diǎn)
它是一個(gè)具體的類,非接口 抽象類箱吕。有一個(gè)重要的create()方法芥驳,利用if或者 switch創(chuàng)建產(chǎn)品并返回。
create()方法通常是靜態(tài)的茬高,所以也稱之為靜態(tài)工廠晚树。
簡(jiǎn)單(靜態(tài))工廠缺點(diǎn)
擴(kuò)展性差(我想增加一種面條,除了新增一個(gè)面條產(chǎn)品類雅采,還需要修改工廠類方法)
不同的產(chǎn)品需要不同額外參數(shù)的時(shí)候 不支持爵憎,因?yàn)閟witch的原因
二. 多方法工廠(常用)
多方法的工廠模式為不同產(chǎn)品,提供不同的生產(chǎn)方法婚瓜,使用時(shí) 需要哪種產(chǎn)品就調(diào)用該種產(chǎn)品的方法宝鼓,使用方便、容錯(cuò)率高巴刻。
-
水果工廠類
class MulWayFruitFactory{ /* 吃蘋果 */ public static Fruit createApple(){ return new AppleFruit(); } /* 吃橘子 */ public static Fruit createOrange(){ return new OrangeFruit(); } /* 吃榴蓮 */ public static Fruit createDurian(){ return new DurianFruit(); } } //測(cè)試 public class Test{ public static void main(String[] args){ Fruit fruit = MulWayFruitFactory.createApple(); fruit.desc(); } }
- 多方法工廠一個(gè)好處在于愚铡,只需要?jiǎng)?chuàng)建產(chǎn)品類以及在工廠類中添加static方法即可
三. 普通工廠(常用)
- 普通工廠就是把簡(jiǎn)單工廠中具體的工廠類,劃分成兩層:抽象工廠層+具體的工廠子類層。(一般->特殊)
水果生產(chǎn)工廠(抽象工廠類)沥寥,作用就是生產(chǎn)水果
abstract class FruitFactory{
public abstract Fruit create();
}
蘋果工廠(具體工廠類)
class AppleFactory extends FruitFactory{
@Override
public Fruit create(){
return new AppleFruit();
}
}
橘子工廠(具體工廠類)
class OrangeFactory extends FruitFactory{
@Override
public Fruit create(){
return new OrangeFruit();
}
}
榴蓮工廠(具體工廠類)
class DurianFactory extends FruitFactory{
@Override
public Fruit create(){
return new DurianFruit();
}
}
測(cè)試:
public class Test{
public static void main(String[] args){
FruitFactory factory = new OrangeFactory();
factory.create().desc();
}
}
/*
在JDK1.8中輸出結(jié)果為:
----------------------
橘子好久沒吃了碍舍,有點(diǎn)酸
----------------------
*/
普通工廠和簡(jiǎn)單工廠區(qū)別:
- 普通工廠模式特點(diǎn):不僅僅做出來(lái)的產(chǎn)品要抽象, 工廠也應(yīng)該需要抽象邑雅。
- 工廠方法使一個(gè)產(chǎn)品類的實(shí)例化延遲到其具體工廠子類.
- 工廠方法的好處就是更擁抱變化片橡。當(dāng)需求變化,只需要增刪相應(yīng)的類淮野,不需要修改已有的類捧书。
- 而簡(jiǎn)單工廠需要修改工廠類的create()方法,多方法靜態(tài)工廠模式需要增加一個(gè)靜態(tài)方法骤星。
- 引入抽象工廠層后经瓷,每次新增一個(gè)具體產(chǎn)品類,也要同時(shí)新增一個(gè)具體工廠類
此工廠方法的理解轉(zhuǎn)載自https://blog.csdn.net/zxt0601/article/details/52798423#commentBox
6. 塊優(yōu)先級(jí)的學(xué)習(xí)
-
Employee類
import java.time.LocalDate; import java.util.Random; class Employee{ private static int nextID; //data field private int id; private String name = ""; private double salary; //static塊 static{ Random random = new Random(); nextID = random.nextInt(10000); } //普通塊 { id =nextID; nextID++; } //三個(gè)重載方法 public Employee(String name,double salary){ this.name = name; this.salary = salary; } public Employee(double salary){ this("hahaha",salary); } public Employee(){ } public String getName(){ return name; } public double getSalary(){ return salary; } public int getId(){ return id; } }
-
EmployeeTest類
public class EmployeeTest{ public static void main(String[] args){ Employee[] staff = new Employee[3]; staff[0] = new Employee("zhangsan",100); staff[1] = new Employee(200); staff[2] = new Employee(); //輸出所有員工信息 for(Employee e : staff){ System.out.println("name : " + e.getName() + " salary : " + e.getSalary() + " id : " + e.getId() ); } } } /* 在JDK1.8中輸出結(jié)果為: --------------------------------------------------------- name : zhangsan salary : 100.0 id : 2269 name : hahaha salary : 200.0 id : 2270 name : salary : 0.0 id : 2271 --------------------------------------------------------- */ /* 此時(shí)可看出優(yōu)先順序 static > 普通塊 */
7. 類設(shè)計(jì)技巧的學(xué)習(xí)
-
一定要保證數(shù)據(jù)私有
- 絕對(duì)不能破壞封裝性
- 保持實(shí)例域的私有性
-
一定要對(duì)數(shù)據(jù)初始化
- 不要依賴系統(tǒng)默認(rèn)值
- 顯式的初始化所有的數(shù)據(jù)
- 初始化方式
- 提供默認(rèn)值
- 構(gòu)造其中設(shè)置默認(rèn)值
-
不要在類中使用過(guò)多的基本類型
- 用其他的類代替多個(gè)相關(guān)的基本類型的使用
不是所有的域都需要獨(dú)立的域訪問(wèn)器和域更改器
-
將職責(zé)過(guò)多的類進(jìn)行分解
- 也不要分解到過(guò)多
類名和方法名要能夠體現(xiàn)他們的職責(zé)
優(yōu)先使用不可變的類