介面
- 介面中只能定義public並且是final的公共靜態常量,不允許定義變數。
- 抽象類可以定義抽象方法和非抽象方法,介面中只能定義公共的,抽象的例項方法。
- 介面只能由其他介面實現繼承
- 子介面繼承的目的在於擁有父介面功能後新增新定義
- 任何一個非抽象類實現介面必需實現所有介面中方法(可以使用介面卡,就不用都實現了)
- 介面被實現目的就是實現業務功能具體化
內部類
內部類的作用
- 內部類通過外部類訪問從而被限定使用許可權
- 內部類所定義功能更多時候只為外部類提供
- 內部類使某些功能使用更加安全
內部類的定義和建立
- 內部類必須定義在某個類中,所在類為其外部類
- 內部類可以使用public,protected,private訪問修飾符
- 內部類可以試用abstract,final,static修飾符
- 內部類沒有單獨的java原始檔,只有class檔案
- 內部類的類檔名稱規範:外部類$內部類.class例:
(1) Computer.Cpu cpu = new Computer().new Cpu();
- 如果是靜態的非例項建立靜態內部類,例子如下:
(1) Computer.Cpu cpu = new Computer.Cpu();
匿名類物件
- 匿名類物件就是直接實現介面。相當於建立了一個類,實現了介面,但是這個類沒有名,直接寫成了new 介面(){},所以叫匿名內部類。
- 匿名類物件就是沒有名稱型別的物件
- 匿名類物件經常作為介面或抽象類的實現
- 匿名類物件可減少介面或者抽象類實現類的定義
- 匿名類物件一定屬於它實現的父級型別
靜態程式碼塊
靜態程式碼塊中的內容
- 靜態程式碼塊中允許訪問靜態屬性
- 靜態程式碼塊中允許呼叫靜態方法
- 靜態程式碼塊中允許定義區域性變數及常量
- 靜態程式碼塊中允許定義區域性類
- 靜態程式碼塊中不能訪問例項屬性和方法及定義方法
靜態程式碼塊的載入
- 靜態程式碼塊屬於類和物件無關,隨類的載入而載入
- 靜態程式碼塊在靜態屬性初始化後與呼叫構造器之前載入
- 靜態程式碼塊在載入時通常做一些靜態屬性或常量的賦值、呼叫靜態方法等工作,如果想在產生任何所在類物件之前類載入時處理類資訊則可以選擇使用靜態程式碼塊完成
/**
*1 企業級專案開發中,通常都會對資料庫中的資料進行增刪改查操作, 實際專案中資料庫的結構(資料庫表)是不同的, 這也體現了業務資料的不同,
* 但是它們有共性的操作,那就是無論什麼業務都會有對資料庫表的增刪改查功能實現,行為動作目的是相同的; 根據本單元及上個單元抽象的概念
* 及理解設計一個介面,能夠提供適合對不同資料庫表同樣的操作的增刪改查抽象方法, 定義若干個普通類實現上述介面並實現介面中的方法, 應
* 考慮以下問題:
* 1)根據給定的字串資訊查詢不同的表並根據實際情況返回不同型別的值;
* 2)根據給定的使用者名稱字串資訊驗證此使用者名稱在對應的資料庫表中是否存在;
* 3)根據給定的多種型別資訊將此資訊儲存到對應的資料庫表中;
* 4)根據給定的不同型別引數刪除符合條件的資料,並返回被刪除了多少條資料.
* 提示: 由於沒有學習到正在的資料庫操作, 所以具體實現抽象方法只要體現不同操作即可.從而理解介面抽象方法定義的意義所在.
* 2 為了在使用上述介面的特定方法, 而不必在介面的實現類中提供不需要的方法,請在任務1的基礎上為介面提供一個介面卡類,改寫實現類繼承
* 這個介面卡.從而避免在介面實現的普通類中出現不需要的方法程式碼實現. 以使得此類程式碼更加精簡.只用需要的方法.
* 3 在某個資料庫表的查詢操作中,需要使用到任務1中介面的某個方法, 但是由於本次操作很特殊,只會在整個應用中執行一次這樣的操作, 為一次
* 這樣的操作而實現介面或繼承介面的介面卡而定義一個java類感覺非常沒有必要, 根據本單元內容及以上任務1和任務2 的實現, 在此基礎上完成
* 對介面中目標方法的呼叫但不單獨定義編寫一個實現介面或繼承介面介面卡的實現程式碼.
* 提示: 內部匿名類物件的作用!!
*/ package test; import adaptor.InterfacesAdaptor;
import imp.SaveDatas;
import imp.deleteData;
import objects.Carrier;
import imp.SearchCarrier;
import imp.SearchUserName;
import interfaces.SearchDatabase;
import objects.DataHangar; import java.util.Scanner; public class Test {
public static void main(String[] args) {
//先來一個Scanner接收使用者輸入
Scanner input = new Scanner(System.in); /**
* 1.1功能 1)根據給定的字串資訊查詢不同的表並根據實際情況返回不同型別的值;
*/
//使用tag接收使用者選擇查詢的資訊
System.out.println("請輸入需要查詢的航母資訊:名稱 排水量");
String tag = input.next(); //以SearchDatabase介面為型別,例項化它的子類SearchCarrier
SearchDatabase search = new SearchCarrier(); //例項化Carrier航母物件
Carrier car = new Carrier(); //呼叫searchCarrier方法,把整個物件作為引數傳過去,接收返回值
Carrier c = search.searchCarrier(car); if (tag.equals("名稱"))
System.out.println(c.getCARRIERSNAME());
else if (tag.equals("排水量"))
System.out.println(c.getCARRIERSWEIGHT()); /**
* 1.2功能 2)根據給定的使用者名稱字串資訊驗證此使用者名稱在對應的資料庫表中是否存在;
*/
//請使用者輸入要查詢的使用者名稱
System.out.println("請輸入您要查詢的使用者名稱:");
String userName = input.next(); //建立例項並呼叫searchUser方法,返回true或false代表有沒有查詢到這個使用者名稱
SearchDatabase ser = new SearchUserName();
//使用布林型別的e接收返回值並列印
boolean e = ser.searchUser(userName);
System.out.println("系統中是否有此使用者名稱:"+e); //例項化子類用get方法獲取正確的使用者名稱看下以便對比,現實中不會給使用者看正確的使用者名稱這樣不符合安全性要求
SearchUserName ser1 = new SearchUserName();
System.out.println("正確的使用者名稱應該是:"+ser1.getUserName()); /**
* 1.3功能 3)根據給定的多種型別資訊將此資訊儲存到對應的資料庫表中;
*/
System.out.println("請輸入您要存到資料庫的使用者名稱:");
String userName1 = input.next(); System.out.println("請輸入您要存到資料庫的密碼:");
int pwd = input.nextInt(); System.out.println("請輸入您要存到資料庫的身高:");
double h = input.nextDouble(); //用介面作為型別去例項化SaveDatas物件
SearchDatabase ser2 = new SaveDatas(); //把使用者輸入的值傳過去呼叫saveData方法,同時用一個DataHangar型別的物件dat接收返回值
DataHangar dat = ser2.saveData(userName1,pwd,h); //列印儲存的結果
System.out.println("存到資料庫的使用者名稱是:"+dat.getUserName());
System.out.println("存到資料庫的密碼是:"+dat.getPwd());
System.out.println("存到資料庫的身高是:"+dat.getH()); /**
* 1.4功能 4)根據給定的不同型別引數刪除符合條件的資料,並返回被刪除了多少條資料.
*/
System.out.println("請輸入您要刪除的資料:1奇數,2偶數");
int signal = input.nextInt(); //使用介面作為型別去例項化deleteData物件
SearchDatabase ser3 = new deleteData();
//定義一個int接收呼叫刪除方法返回的刪除資料的個數
int receive = ser3.deleteData(signal);
System.out.println("刪除了"+receive+"個數據"); /**
* 3.1功能 使用匿名類物件執行一個登陸操作
*/
//定義使用者名稱為king23,密碼為123456
String n = "king23";
String p = "123456";
/**
* 使用匿名類物件,把使用者名稱和密碼作為引數傳給這個物件
*/
InterfacesAdaptor(n, p,new InterfacesAdaptor() {
//重寫並呼叫父類介面中的驗證密碼的方法,如果和類的引數相等,返回true,驗證通過
@Override
public boolean validatePassword(String loginName, String pwd) {
if (loginName != null && loginName.equals("king23")
&& pwd != null && !pwd.equals("") && pwd.equals("123456"))
return YEAH;
else
return NOPE;
}
}); }
//定義一個驗證密碼的靜態方法
public static void InterfacesAdaptor(String name,String pwd,InterfacesAdaptor inte){
boolean res1 = inte.validatePassword(name,pwd);
System.out.println("登入是否成功:"+res1);
} }
package interfaces; import objects.Carrier;
import objects.DataHangar; public interface SearchDatabase { /**
* 1)根據給定的字串資訊查詢不同的表並根據實際情況返回不同型別的值;
* @return
*/
Carrier searchCarrier(Carrier carrier); /**
* 2)根據給定的使用者名稱字串資訊驗證此使用者名稱在對應的資料庫表中是否存在;
* 返回值是布林型別,存在返回true,不存在返回false
* @param userName
* @return
*/
boolean YESE = true;
boolean NOT = false; boolean searchUser(String userName); /**
* 3)根據給定的多種型別資訊將此資訊儲存到對應的資料庫表中;
*/
//定義一個儲存資料的方法,向DataHangar儲存使用者名稱,密碼,身高三個資料
DataHangar saveData(String userName,int pwd,double h); /**
* 4)根據給定的不同型別引數刪除符合條件的資料,並返回被刪除了多少條資料.
*/
int deleteData(int signal); /**
* * 3 在某個資料庫表的查詢操作中,需要使用到任務1中介面的某個方法, 但是由於本次操作很特殊,只會在整個應用中執行一次這樣的操作, 為一次
* * 這樣的操作而實現介面或繼承介面的介面卡而定義一個java類感覺非常沒有必要, 根據本單元內容及以上任務1和任務2 的實現, 在此基礎上完成
* * 對介面中目標方法的呼叫但不單獨定義編寫一個實現介面或繼承介面介面卡的實現程式碼.
* * 提示: 內部匿名類物件的作用!!
*/
boolean YEAH = true;
boolean NOPE = false; boolean validatePassword(String loginName,String pwd);
}
/**
* 2 為了在使用上述介面的特定方法, 而不必在介面的實現類中提供不需要的方法,
* 請在任務1的基礎上為介面提供一個介面卡類,改寫實現類繼承這個介面卡.從而避
* 免在介面實現的普通類中出現不需要的方法程式碼實現. 以使得此類程式碼更加精簡.
* 只用需要的方法.
*/ package adaptor; import objects.Carrier;
import interfaces.SearchDatabase;
import objects.DataHangar; //定義一個介面卡類,實現介面,並給介面所有的方法提供一個空實現
public class InterfacesAdaptor implements SearchDatabase {
@Override
public Carrier searchCarrier(Carrier carrier) {
return null;
} @Override
public boolean searchUser(String userName) {
return false;
} @Override
public DataHangar saveData(String userName, int pwd, double h) {
return null;
} @Override
public int deleteData(int signal) {
return 0;
} @Override
public boolean validatePassword(String loginName, String pwd) {
return false;
} }
/**
* 這個類用來實現1.1功能 1)根據給定的字串資訊查詢不同的表並根據實際情況返回不同型別的值;
* 根據提供的查詢資訊,返回航母的引數
*/ package imp; import adaptor.InterfacesAdaptor;
import objects.Carrier; public class SearchCarrier extends InterfacesAdaptor { //重寫介面中的抽象方法
@Override
public Carrier searchCarrier(Carrier carrier) { return carrier;
} }
/**
* 這個類用來實現介面中查詢使用者名稱的功能
* 2)根據給定的使用者名稱字串資訊驗證此使用者名稱在對應的資料庫表中是否存在;
*/ package imp; import adaptor.InterfacesAdaptor; public class SearchUserName extends InterfacesAdaptor {
//模擬資料庫中存了一個使用者名稱叫測試使用者
private String userName = "測試使用者"; @Override
public boolean searchUser(String userName) {
//判斷如果傳過來的字串相等就返回true否則返回false
if(this.userName.equals(userName) )
return YESE;
else
return NOT;
} public String getUserName() {
return userName;
} }
/**
* 3)根據給定的多種型別資訊將此資訊儲存到對應的資料庫表中;
*/ package imp; import adaptor.InterfacesAdaptor;
import objects.DataHangar; public class SaveDatas extends InterfacesAdaptor {
@Override
public DataHangar saveData(String userName, int pwd, double h) {
//例項化DataHanger物件,使用set方法把接收到的值存到這個物件的成員變數當中,最後返回這個物件
DataHangar dat = new DataHangar();
dat.setUserName(userName);
dat.setPwd(pwd);
dat.setH(h);
return dat;
}
}
/**
* 1.4功能 4)根據給定的不同型別引數刪除符合條件的資料,並返回被刪除了多少條資料.
*/ package imp; import adaptor.InterfacesAdaptor; public class deleteData extends InterfacesAdaptor {
//定義一個數組,模擬資料庫存了5個奇數和4個偶數
int arrayList1[] = {1,2,3,4,5,6,7,8,9};
int count = 0; @Override
public int deleteData(int signal) {
if (signal == 1){ //如果判斷是奇數,count++,百度到刪除陣列元素操作很複雜,所以沒有去實現刪除操作
for (int i=0;i<arrayList1.length;i++){
if (arrayList1[i]%2==1)
count++;
}
return count;
}else if(signal == 2){ //如果判斷是偶數,count++,百度到刪除陣列元素操作很複雜,所以沒有去實現刪除操作
for (int i=0;i<arrayList1.length;i++){
if (arrayList1[i]%2==0)
count++;
}
return count;
}else
return 0;
}
}
//封裝一個航母類,提供getter和setter方法 package objects; public class Carrier {
private String CARRIERSNAME = "遼寧號";
private int CARRIERSWEIGHT = 65000; public String getCARRIERSNAME() {
return CARRIERSNAME;
} public void setCARRIERSNAME(String CARRIERSNAME) {
this.CARRIERSNAME = CARRIERSNAME;
} public int getCARRIERSWEIGHT() {
return CARRIERSWEIGHT;
} public void setCARRIERSWEIGHT(int CARRIERSWEIGHT) {
this.CARRIERSWEIGHT = CARRIERSWEIGHT;
} }
//封裝一個數據倉庫類,提供getter和setter方法 package objects; public class DataHangar {
private String userName;
private int pwd;
private double h; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public int getPwd() {
return pwd;
} public void setPwd(int pwd) {
this.pwd = pwd;
} public double getH() {
return h;
} public void setH(double h) {
this.h = h;
}
}
--------------------------------分割線-----------------------------------
內部類和靜態程式碼塊案例
package staticBlock;
//主方法
public class TestStaticBlock {
public static void main(String[] args) {
System.out.println(DataSourceManager.getURL());
}
}
package staticBlock; public class DataSourceManager { private static final String URL;
private static final String DRIVER;
private static final String USER;
private static final String PASSWORD; //因為是靜態的常量,所以沒有setter方法,只有getter方法
public static String getURL() {
return URL;
} public static String getDRIVER() {
return DRIVER;
} public static String getUSER() {
return USER;
} public static String getPASSWORD() {
return PASSWORD;
} //通過定義一個靜態方法的方式去例項化靜態程式碼塊
static DataSourceManager self;
private static void newInstanceOfDataSourceManager(){
self = new DataSourceManager();
}
//定義一個靜態程式碼塊
static {
/* static塊中不允許直接定義任何方法
void m(){ }*/
//定義一個內部類
class InnerClass{
public void printMessage(){
System.out.println("我是定義在static塊中的內部區域性類");
}
}
URL = "jdbc:mysql://localhost:3306/test";
DRIVER = "com.mysql.jdbc.Driver";
USER = "root";
PASSWORD = "root";
//如果self不為空,則執行靜態的方法去例項化靜態程式碼塊
if (self!=null)
newInstanceOfDataSourceManager();
//例項化內部類,由於程式碼塊在載入的時候就會被執行,所以會輸出語句我是定義在static塊中的內部類
InnerClass inner = new InnerClass();
inner.printMessage();
}
//定義一個私有的構造器
private DataSourceManager(){ }
}