3 月的碎碎念,大致總結了商業人生、付費軟體、創業方向選擇、創業感性還是理性、如何解決複雜問題及如何成長這幾個方面的內容。 商業人生 商業人生需要試錯能力和快速信息收集與驗證校準; 商業邏輯需要試錯能力,收集各種渠道信息後整理決策。快速信息收集和驗證校準很重要。 付費軟體 付費軟體產品可以依托大平臺 ...
static關鍵字
static是靜態修飾符,一般修飾成員。被static修飾的成員屬於類,不屬於單個這個類的某個對象。static修飾的成員被多個對象共用。static修飾的成員屬於類,但是會影響每一個對象。被static修飾的成員又叫類成員,不叫對象的成員。
static特點
被static修飾的成員變數屬於類,不屬於這個類的某個對象。
class Demo {
public static int num = 100;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.num = 200;
System.out.println(d1.num); //結果為200
System.out.println(d2.num); //結果為200
}
}
靜態內容是優先於對象存在,只能訪問靜態,不能使用this/super。靜態修飾的內容存於靜態區。
class Demo {
//成員變數
public int num = 100;
//靜態方法
public static void method(){
//this.num; 不能使用this/super。
//System.out.println(this.num);//報錯
}
}
同一個類中,靜態成員只能訪問靜態成員
class Demo {
//成員變數
public int num = 100;
//靜態成員變數
public static int count = 200;
//靜態方法
public static void method(){
//System.out.println(num); 靜態方法中,只能訪問靜態成員變數或靜態成員方法
System.out.println(count);
}
}
static使用格式
被static修飾的成員可以並且建議通過類名直接訪問。
類名.靜態成員變數名
類名.靜態成員方法名(參數)
對象名.靜態成員變數名 // 不建議使用
對象名.靜態成員方法名(參數) // 不建議使用
class Demo {
//靜態成員變數
public static int num = 100;
//靜態方法
public static void method(){
System.out.println("靜態方法");
}
}
class Test {
public static void main(String[] args) {
System.out.println(Demo.num);
Demo.method();
}
}
靜態代碼塊
靜態代碼塊:定義在成員位置,使用static修飾的代碼塊{ }。
- 位置:類中方法外。
- 執行:隨著類的載入而執行且執行一次,優先構造方法的執行。
public class Person {
private String name;
private int age;
//靜態代碼塊
static{
System.out.println("靜態代碼塊執行了");
}
}
定義靜態常量
開發中,我們想在類中定義一個靜態常量,通常使用public static final修飾的變數來完成定義。此時變數名用全部大寫,多個單詞使用下劃線連接。
定義格式:
public static final 數據類型 變數名 = 值;
class Company {
//比如公司名稱公司地址 可能會很長很長 我們記不住 每次使用還容易打錯
//這時將其定義為靜態常量 方便訪問 還不容易出錯
public static final String COMPANY_NAME = "我的公司";
}
當我們想使用類的靜態成員時,不需要創建對象,直接使用類名來訪問即可。
System.out.println(Company.COMPANY_NAME);
註意:介面中的每個成員變數都預設使用public static final修飾。
所有介面中的成員變數已是靜態常量,由於介面沒有構造方法,所以必須顯示賦值。可以直接用介面名訪問。
interface Inter {
public static final int COUNT = 100;
}
訪問介面中的靜態變數
Inter.COUNT
靜態導入(瞭解)
靜態導入就是java包的靜態導入,使用import static 靜態導入包 , 這樣可以直接使用方法名去調用靜態的方法。
靜態導入格式:
import static 包名.類名.方法名;
import static 包名.類名.*;
定義A類 如下, 含有兩個靜態方法 :
public class A {
public static void print(Object s){
System.out.println(s);
}
public static void print2(Object s){
System.out.println(s);
}
}
靜態導入一個類的某個靜態方法 , 使用static和類名A .方法名 , 表示導入A類中的指定方法 , 代碼演示 :
import static com.paopao.A.print;
public class Demo {
public static void main(String[] args) {
print("test string");
}
}
如果有多個靜態方法 , 使用static和類名A . * , 表示導入A類里的所有的靜態方法, 代碼演示 :
import static com.paopao.A.*;
public class Demo {
public static void main(String[] args) {
print("test string");
print2("test2 string");
}
}
許可權修飾符
在Java中提供了四種訪問許可權,使用不同的訪問許可權修飾符修飾時,被修飾的內容會有不同的訪問許可權,
- public:公共的。
- protected:受保護的
- default:預設的
- private:私有的
不同許可權的訪問能力
public | protected | default(空的) | private | |
---|---|---|---|---|
同一類中 | √ | √ | √ | √ |
同一包中(子類與無關類) | √ | √ | √ | |
不同包的子類 | √ | √ | ||
不同包中的無關類 | √ |
可見,public具有最大許可權。private則是最小許可權。
編寫代碼時,如果沒有特殊的考慮,建議這樣使用許可權:
- 成員變數使用
private
,隱藏細節。 - 構造方法使用
public
,方便創建對象。 - 成員方法使用
public
,方便調用方法。
不加許可權修飾符,其訪問能力與default修飾符相同
內部類
將一個類A定義在另一個類B裡面,裡面的那個類A就稱為內部類,B則稱為外部類。
成員內部類
- 成員內部類 :定義在類中方法外的類。
定義格式:
class 外部類 {
class 內部類{
}
}
在描述事物時,若一個事物內部還包含其他事物,就可以使用內部類這種結構。比如,汽車類Car
中包含發動機類Engine
,這時,Engine
就可以使用內部類來描述,定義在成員位置。
代碼舉例:
class Car { //外部類
class Engine { //內部類
}
}
訪問特點
-
內部類可以直接訪問外部類的成員,包括私有成員。
-
外部類要訪問內部類的成員,必須要建立內部類的對象。
創建內部公共(public)類對象格式:
外部類名.內部類名 對象名 = new 外部類型().new 內部類型();
訪問演示,代碼如下:
定義類:
public class Person {
private boolean live = true;
class Heart {
public void jump() {
// 直接訪問外部類成員
if (live) {
System.out.println("心臟在跳動");
} else {
System.out.println("心臟不跳了");
}
}
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
}
定義測試類:
public class InnerDemo {
public static void main(String[] args) {
// 創建外部類對象
Person p = new Person();
// 創建內部類對象
Person.Heart heart = p.new Heart();
// 調用內部類方法
heart.jump();
// 調用外部類方法
p.setLive(false);
// 調用內部類方法
heart.jump();
}
}
輸出結果:
心臟在跳動
心臟不跳了
內部類仍然是一個獨立的類,在編譯之後會內部類會被編譯成獨立的.class文件,但是前面冠以外部類的類名和$符號
比如,Person$Heart.class
匿名內部類
- 匿名內部類 :是內部類的簡化寫法。它的本質是一個
帶具體實現的
父類或者父介面的
匿名的
子類對象。
開發中,最常用到的內部類就是匿名內部類了。以介面舉例,當你使用一個介面時,似乎得做如下幾步操作,
- 定義子類
- 重寫介面中的方法
- 創建子類對象
- 調用重寫後的方法
格式
new 父類名或者介面名(){
// 方法重寫
@Override
public void method() {
// 執行語句
}
};
使用方式
以介面為例,匿名內部類的使用,代碼如下:
定義介面:
public abstract class FlyAble{
public abstract void fly();
}
匿名內部類可以通過多態的形式接受
public class InnerDemo01 {
public static void main(String[] args) {
/*
1.等號右邊:定義並創建該介面的子類對象
2.等號左邊:是多態,介面類型引用指向子類對象
*/
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飛了~~~");
}
};
}
}
匿名內部類直接調用方法
public class InnerDemo02 {
public static void main(String[] args) {
/*
1.等號右邊:定義並創建該介面的子類對象
2.等號左邊:是多態,介面類型引用指向子類對象
*/
new FlyAble(){
public void fly() {
System.out.println("我飛了~~~");
}
}.fly();
}
}
方法的形式參數是介面或者抽象類時,也可以將匿名內部類作為參數傳遞
public class InnerDemo3 {
public static void main(String[] args) {
/*
1.等號右邊:定義並創建該介面的子類對象
2.等號左邊:是多態,介面類型引用指向子類對象
*/
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飛了~~~");
}
};
// 將f傳遞給showFly方法中
showFly(f);
}
public static void showFly(FlyAble f) {
f.fly();
}
}
以上可以簡化,代碼如下:
public class InnerDemo2 {
public static void main(String[] args) {
/*
創建匿名內部類,直接傳遞給showFly(FlyAble f)
*/
showFly( new FlyAble(){
public void fly() {
System.out.println("我飛了~~~");
}
});
}
public static void showFly(FlyAble f) {
f.fly();
}
}
引用類型的傳遞
類名作為方法參數和返回值
-
類名作為方法的形參
方法的形參是類名,其實需要的是該類的對象
實際傳遞的是該對象的【地址值】
-
類名作為方法的返回值
方法的返回值是類名,其實返回的是該類的對象
實際傳遞的,也是該對象的【地址值】
-
示例代碼:
public class Person{ public void eat(){ System.out.println("人吃了"); } } public class Test{ public static void main(String[] args){ method(new Person()); Person p = method2(); } pubic static void method(Person p){ p.eat(); } public static Person method2(){ return new Person(); } }
抽象類作為形參和返回值
-
抽象類作為形參和返回值
- 方法的形參是抽象類名,其實需要的是該抽象類的子類對象
- 方法的返回值是抽象類名,其實返回的是該抽象類的子類對象
-
示例代碼:
public abstract class Animal{ public abstract void eat(); } public class Cat extends Animal{ public void eat(){ System.out.println("貓吃魚"); } } public class Test{ public static void main(String[] args){ method(new Cat()); Animal a = method2(); } public static void method(Animal a){ a.eat(); } public static Animal method2(){ return new cat(); } }
介面名作為形參和返回值
-
介面作為形參和返回值
- 方法的形參是介面名,其實需要的是該介面的實現類對象
- 方法的返回值是介面名,其實返回的是該介面的實現類對象
-
示例代碼:
public interface Fly{ public abstract void fly(); } public class Bird implements Fly{ public void fly(){ System.out.println("我飛了"); } } public class Test{ public static void main(String[] args){ method(new Bird()); Fly f = method2(); } public static void method(Fly f){ f.fly(); } public static Fly method2(){ return new Bird(); } }
練習
公司類
屬性
總資產屬性
所有員工屬性
方法
發工資方法:從總資產中減去所有員工支出。
員工:
屬性
姓名
工號
存款
工資
經理、廚師、服務員均為員工子類。經理在員工基礎上添加獎金屬性。發完工資後,請查看所有員工的存款情況.
公司類加入調整員工工資方法:返回值為void
參數為:被調整工資的員工與調整金額(漲工資為正數、降工資為負數)。
方法體邏輯為,在員工工資的基礎上調整相應的金額
在上邊需求基礎上,添加評選幸運員工(隨機抽取一名員工並返回)。
點擊查看代碼
// Employee.java
public class Employee {
String name;
String id;
private double deposit;
private double salary;
public Employee() {}
public Employee(String name, String id, double deposit, double salary) {
this.name = name;
this.id = id;
this.deposit = deposit;
this.salary = salary;
}
public double getDeposit() {
return deposit;
}
public void setDeposit(double deposit) {
this.deposit = deposit;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
// Manager.java
public class Manager extends Employee {
private double bonus;
public Manager() {
}
public Manager(String name, String id, double deposit, double salary, double bonus) {
super(name, id, deposit, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bouns) {
this.bonus = bouns;
}
}
// Cooker.java
public class Cooker extends Employee {
public Cooker() {
}
public Cooker(String name, String id, double deposit, double salary) {
super(name, id, deposit, salary);
}
}
// Waiter.java
public class Waiter extends Employee{
public Waiter() {
}
public Waiter(String name, String id, double deposit, double salary) {
super(name, id, deposit, salary);
}
}
// Company.java
import java.util.ArrayList;
import java.util.Random;
public class Company {
private double property;
private ArrayList<Employee> employeeArrayList;
public Company() {
}
public Company(double property, ArrayList<Employee> employeeArrayList) {
this.property = property;
this.employeeArrayList = employeeArrayList;
}
public double getProperty() {
return property;
}
public void setProperty(double property) {
this.property = property;
}
public ArrayList<Employee> getEmployeeArrayList() {
return employeeArrayList;
}
public void setEmployeeArrayList(ArrayList<Employee> employeeArrayList) {
this.employeeArrayList = employeeArrayList;
}
public Boolean existEmployee(){
if (employeeArrayList == null || employeeArrayList.size() == 0) {
return false;
}
return true;
}
public void printEmployeeInfo(Employee employee) {
System.out.println("工號: " + employee.id);
System.out.println("姓名: " + employee.name);
System.out.println("存款: " + employee.getDeposit());
System.out.println("工資: " + employee.getSalary());
if (employee instanceof Manager) {
System.out.println("獎金: " + ((Manager) employee).getBonus());
}
System.out.println("==============================");
}
public void showEmployeeInfo() {
ArrayList<Employee> employeeArrayList = getEmployeeArrayList();
if (!existEmployee()){
System.out.println("暫無員工");
return ;
}
for (int i = 0; i < employeeArrayList.size(); i++) {
Employee employee = employeeArrayList.get(i);
printEmployeeInfo(employee);
}
}
public void showEmployeeInfo(Employee employee){
printEmployeeInfo(employee);
}
public void payingSalaries() {
if (!existEmployee()){
System.out.println("暫無員工");
return ;
}
for (int i = 0; i < employeeArrayList.size(); i++) {
Employee employee = employeeArrayList.get(i);
property -= employee.getSalary();
employee.setDeposit(employee.getDeposit() + employee.getSalary());
if (employee instanceof Manager) {
property -= ((Manager) employee).getBonus();
employee.setDeposit(employee.getDeposit() + ((Manager) employee).getBonus());
}
}
}
public Employee randomEmployee() {
Random r = new Random();
return employeeArrayList.get(r.nextInt(employeeArrayList.size()));
}
public void chageSalary(Employee employee, double howMuch) {
employee.setSalary(employee.getSalary() + howMuch);
}
}
// Demo.java
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<Employee> employeeArrayList = new ArrayList<>();
employeeArrayList.add(new Manager("張三","001",10000,2000,3000));
employeeArrayList.add(new Cooker("李四","002",1000, 2000));
employeeArrayList.add(new Waiter("王五","003",2000,2000));
Company company = new Company(1000000, employeeArrayList);
company.showEmployeeInfo();
company.payingSalaries();
company.showEmployeeInfo();
Employee employee = company.randomEmployee();
company.showEmployeeInfo(employee);
company.chageSalary(employee, -200);
System.out.println(employee.getSalary());
}
}