2、面向對象簡介
Java語言最大特點:面向對象程式設計設計
面向過程:C語言,面對一個問題的解決方案
面向對象:C++/Java,子產品化設計,進行重用配置,考慮标準
1、面向對象三個主要特征:
封裝性:内部操作對外部不可見
繼承性:已有結構的基礎上繼續進行功能擴充
多态性:是在繼承性的基礎上擴充而來的概念,指類型的轉換處理
2、面向對象開發三個步驟:
OOA:面向對象分析
OOD:面向對象設計
OOP:面向對象程式設計
3、類與對象
類:對某一類事物共性的抽象
對象:描述一個具體的産物
類是一個模型,對象是類可以使用的執行個體
先有類再有對象
類的組成:
成員屬性Field 簡稱屬性
操作方法Method 對象的行為
4、類與對象的定義及使用
Java中,類是一個獨立的結構體
屬性就是變量
方法就是可以重複執行的代碼
// 定義類
class Person {
// 定義屬性
String name; // 引用資料類型 預設值 null
int age; // 基礎資料類型 預設值 0
// 定義方法
public void tell(){
System.out.println("姓名:" + this.name + " 年齡:" + this.age);
}
public static void main(String[] args) {
Person person = new Person();
person.name = "張三";
person.age = 18;
person.tell();
// 姓名:張三 年齡:18
}
}
生産對象兩種方式:
1、聲明并執行個體化對象
類名稱 對象名稱 = new 類名稱();
2、分步完成
(1)聲明對象:類名稱 對象名稱 = null;
(2)執行個體化對象:對象名稱 = new 類名稱();
執行個體化對象調用操作:
調用屬性:執行個體化對象.成員屬性;
調用方法:執行個體化對象.方法名稱();
5、記憶體對象分析
最常用的2塊記憶體空間
堆記憶體:儲存對象具體資訊 new開辟堆記憶體空間
棧記憶體:儲存一塊堆記憶體位址
/**
棧記憶體 堆記憶體
位址Ox0001 -> 對象内容
*/
// 方式一
Person person = new Person();
// 方式二
Person person = null;
person = new Person();
所有的對象在調用屬性或方法之前,必須執行個體化
6、對象引用分析
同一塊堆記憶體可以被不同的棧記憶體所指向,也可以更換指向
修改person2, person1也會被修改
Person person1 = new Person();
person1.name = "張三";
person1.age = 19;
Person person2 = person1;
person2.tell();
// 姓名:張三 年齡:19
引用傳遞可以發生在方法調用
public static void main(String[] args) {
Person person = new Person();
person.name = "張三";
person.age = 18;
change(person); // 相當于: Person temp = person;
person.tell();
// 姓名:李四 年齡:18
}
public static void change(Person temp){
temp.name = "李四";
// 方法結束後斷開引用
}
7、引用于垃圾産生分析
垃圾空間:沒有任何棧記憶體指向的堆記憶體空間
垃圾會被GC(Garbage Collector)垃圾收集器定期回收
垃圾過多會影響GC性能
一個棧記憶體隻能儲存有一個堆記憶體的位址資料
Person person1 = new Person(); // Ox0001
Person person2 = new Person(); // Ox0002
person2 = person1; // 此時 person2 指向的 Ox0002 對象成為了垃圾
8、成員屬性封裝
封裝:對資料進行保護
private關鍵字對外不可見
使用setter、getter設定或擷取屬性
類中的所有屬性都必須使用private封裝,需要提供setter、getter方法
class Person {
// 私有化屬性
private String name;
// 對外提供geter, setter方法
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
public static void main(String[] args) {
Person person = new Person();
person.setName("張三");
System.out.println(person.getName());
// 張三
}
}
9、構造方法與匿名對象
現有程式使用類,經過了2個步驟:
1、聲明執行個體化對象,隻能使用預設值
2、通過 setter 方法設定屬性
構造方法: 執行個體化對象時進行資料初始化
1、構造方法名與類名必須一緻
2、構造方法無傳回值
3、構造方法在new執行個體化對象時自動調用
class Person {
// 私有化屬性
private String name;
// 有參構造方法
public Person(String n){
name = n;
}
public static void main(String[] args) {
Person person = new Person("張三");
System.out.println(person.getName());
// 張三
}
}
(1)Person 定義對象所屬類型,類型決定可以調用的方法
(2)person 執行個體化對象的名稱
(3)new 開辟新的堆記憶體空間
(4)Person(“張三”) 調用構造函數(有參,無參)
所有的類都會提供有無參構造方法,程式編譯時自動建立,如果明确構造方法則不自動建立
結論:一個類至少存在一個構造方法
問題:構造方法沒有傳回值?不使用void
構造方法與普通方法差別:
構造方法在類對象執行個體化時調用
普通方法在類對象執行個體化之後調用
構造方法重載
隻用考慮方法簽名(參數個數,類型,順序)
按照參數數量順序排列構造方法
class Person {
// 私有化屬性
private String name;
// 無參構造方法
public Person(){
}
// 有參構造方法
public Person(String n){
name = n;
}
public String getName(){
return name;
}
public static void main(String[] args) {
Person person = new Person("張三");
System.out.println(person.getName());
// 張三
}
}
匿名對象
new Person("張三").getName());
// 張三
使用一次後就會被GC回收釋放
方法可以傳遞基本資料類型和引用資料類型
10、this調用本類屬性
三類描述
1、目前類中的屬性 this.屬性
2、目前類中的方法(構造方法:this()、普通方法:this.方法())
3、描述目前對象
通路本類中的屬性一定要加this
public Person(String name, int age){
this.name = name ;
this.age = age ;
}
11、this調用本類方法
1、調用普通方法
setName(name) ;
// 或者
this.setName(name) ;
好的代碼:
代碼結構可以重用
沒有重複代碼
2、調用構造方法
this()
必須在執行個體化新對象的時候調用
隻允許放在構造函數首行
互相調用必須有出口
// 無參構造方法
public Person(){
this("張三");
}
// 有參構造方法
public Person(String name){
this.name = name;
}
構造方法調用實作預設參數
class Person {
// 私有化屬性
private String name;
private int age;
// 無參構造方法
public Person(){
this("張三");
}
// 一參構造方法
public Person(String name){
this(name, 21);
}
// 兩參構造方法
public Person(String name, int age){
this.name = name;
this.age = age ;
}
public void getInfo(){
System.out.println("name: " + this.name + " age: " + this.age);
}
public static void main(String[] args) {
new Person().getInfo();
new Person("李四").getInfo();
new Person("王五", 22).getInfo();
/*
name: 張三 age: 21
name: 李四 age: 21
name: 王五 age: 22
*/
}
}
12、綜合實戰:簡單Java類
簡單Java類:
可以描述某一類資訊的程式類,沒有特别複雜的操作,隻作為一種資訊存儲的媒介
核心結構
1、類名有意義,明确描述某一類事物
2、屬性必須使用private封裝,提供setter、getter
3、可以提供多個構造方法,必須保留無參構造方法
4、不允許有任何輸出,内有擷取必須傳回
非必須:
1、可以提供擷取對象詳細資訊方法,getInfo()
涉及概念
資料類型、類的定義、private封裝、方法定義、對象執行個體化
class Person {
// 私有化屬性
private String name;
private int age;
// 無參構造方法
public Person(){
this("張三", 23);
}
// 兩參構造方法
public Person(String name, int age){
this.name = name;
this.age = age ;
}
// setter getter
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name ;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age ;
}
public String getInfo(){
return "name: " + this.name + " age: " + this.age;
}
public static void main(String[] args) {
System.out.println(new Person("王五", 22).getInfo());
// name: 王五 age: 22
}
}
13、聲明static屬性
static修飾的屬性為公共屬性,一個對象修改,所有對象都會被修改
應該由類來進行通路,而不是對象,可以由類名來調用
static 屬性不受類執行個體化限制,不執行個體化也可以調用
進行類設計時首選非static屬性,涉及公共資訊才使用static
全局資料區 棧記憶體 堆記憶體
static 資料 person1 -> {name, age}
person1 -> {name, age}
class Person {
String name;
static String country;
public Person(String name){
this.name = name;
}
public static void main(String[] args) {
Person person1 = new Person("張三");
Person person2 = new Person("李四");
Person.country = "中國";
System.out.println(person1.country);
System.out.println(person2.country);
// 中國 中國
}
}
14、聲明static方法
static方法隻允許調用static屬性或static方法
static屬性和方法都可以在沒有執行個體化對象的前提下使用
應用場景:
回避執行個體化對象調用并且描述公共屬性的情況
15、static應用案例
實作執行個體化對象個數統計
class Person {
static int count;
public Person(){
count ++;
System.out.println("第 " + count + " 個執行個體");
}
public static void main(String[] args) {
new Person();
new Person();
new Person();
/*
第 1 個執行個體
第 2 個執行個體
第 3 個執行個體
*/
}
}
16、普通代碼塊
代碼塊:由"{}"定義的結構
分類:
1、普通代碼塊
2、構造代碼塊
3、靜态代碼塊
4、同步代碼塊(多線程)
普通代碼塊
定義在方法中的代碼塊
// 普通代碼塊
{
int age = 12;
System.out.println(age); // 12
}
int age = 15;
System.out.println(age); // 15
17、構造代碼塊
構造塊優先于構造方法執行,每次執行個體化都會調用構造代碼塊
class Person {
public Person(){
System.out.println("構造方法");
}
{
System.out.println("構造代碼塊");
}
public static void main(String[] args) {
new Person();
new Person();
/**
構造代碼塊
構造方法
構造代碼塊
構造方法
*/
}
}
18、靜态代碼塊
static關鍵字定義的代碼塊
靜态代碼塊優先于構造函數執行,不管執行個體化多少次隻會執行一次
主要目的是為了靜态屬性初始化
靜态代碼塊優先于主方法先執行
class Person {
public Person(){
System.out.println("構造方法");
}
{
System.out.println("構造代碼塊");
}
static {
System.out.println("靜态代碼塊");
}
public static void main(String[] args) {
System.out.println("主方法代碼塊");
new Person();
new Person();
/**
靜态代碼塊
主方法代碼塊
構造代碼塊
構造方法
構造代碼塊
構造方法
/
}
}
19、案例分析一(Address)
實作一個位址類,包含國家,省份,城市,街道,郵政編碼
實作一個簡單java類
class Address {
private String country;
private String province;
private String city;
private String street;
private String zipcode;
// setter
public void setCountry(String country){
this.country = country;
}
public void setProvince(String province){
this.province = province;
}
public void setCity(String city){
this.city = city;
}
public void setStreet(String street){
this.street = street;
}
public void setZipcode(String zipcode){
this.zipcode = zipcode;
}
// getter
public String getCountry(){
return this.country;
}
public String getProvince(){
return this.province;
}
public String getCity(){
return this.city;
}
public String getStreet(){
return this.street;
}
public String getZipcode(){
return this.zipcode;
}
// info
public String getInfo(){
return "國家: " + this.country +
", 省份: " + this.province +
", 城市: " + this.city +
", 街道: " + this.street +
", 郵政編碼: " + this.zipcode;
}
public Address(String country, String province, String city, String street, String zipcode){
this.country = country;
this.province = province;
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public static void main(String[] args) {
Address address = new Address("中國", "北京", "朝陽", "大望路", "10001");
System.out.println(address.getInfo());
// 國家: 中國, 省份: 北京, 城市: 朝陽, 街道: 大望路, 郵政編碼: 10001
}
}
20、案例分析二(Employee)
實作一個員工類,包含編号,姓名,薪水,稅率,還包括薪水增長計算和增長後的工資
class Employee{
private long no;
private String name;
private double salary;
private double rate;
// setter getter ...
public String getInfo(){
return "編号:" + this.no +
", 姓名: " + this.name +
", 薪水 " + this.salary +
", 漲幅: " + this.rate;
}
public void increaseSalary(){
this.salary = this.salary * (1 + this.rate);
}
public Employee(long no, String name, double salary, double rate){
this.no = no;
this.name = name;
this.salary = salary;
this.rate = rate;
}
public static void main(String[] args){
Employee employee = new Employee(1L, "張三", 3000.0, 0.3);
System.out.println(employee.getInfo());
// 編号:1, 姓名: 張三, 薪水 3000.0, 漲幅: 0.3
employee.increaseSalary();
System.out.println(employee.getInfo());
// 編号:1, 姓名: 張三, 薪水 3900.0, 漲幅: 0.3
}
}
21、案例分析三(Dog)
建立Dog類,有名字,顔色,年齡,定義構造方法初始化屬性
class Dog{
private String name;
private String color;
private int age;
// getter setter
public Dog(String name, String color, int age){
this.name=name;
this.color=color;
this.age=age;
}
public static void main(String[] args) {
Dog dog = new Dog("小黑", "黑色", 2);
}
}
22、案例分析四(Account)
定義銀行賬戶類,包括
1、資料:賬戶名稱,賬戶餘額
2、方法:開戶(設定賬号,餘額),利用構造方法完成
3、查詢餘額
class Account{
private String name;
private double balance;
public Account(String name){
this(name, 0.0);
}
public Account(String name, double balance){
this.name = name;;
this.balance = balance;;
}
// 查詢餘額
public double getBalance(){
return this.balance;
}
public static void main(String[] args) {
Account account = new Account("張三", 2000.0);
System.out.println(account.getBalance());
// 2000.0
}
}
23、案例分析五(User)
建立使用者類
1、使用者名,記錄使用者個數
2、擷取使用者數
class User{
private String name;
private static int count = 0;
public User(String name){
this.name = name;
count++;
}
public static int getCount(){
return count;
}
public static void main(String[] args) {
User user1 = new User("小明");
User user2 = new User("小紅");
User user3 = new User("小花");
System.out.println(User.getCount());
// 3
}
}
24、案例分析六(Book)
建立圖書類
資料:書名,價格,編号(利用靜态資料實作自動編号)
方法:統計總數
class Book{
private int uid;
private String name;
private double price;
private static int count = 0;
public Book(String name, Double price){
count++;
this.uid = count;
this.name = name ;
this.price = price ;
}
public String getInfo(){
return "<"+ this.uid + "> <<" + this.name +">> "+ this.price;
}
public static int getCount(){
return count;
}
public static void main(String[] args) {
Book book1 = new Book("今日頭條", 12.0);
Book book2 = new Book("百度", 14.0);
Book book3 = new Book("騰訊", 11.0);
System.out.println(Book.getCount());
// 3
System.out.println(book3.getInfo());
// <3> <<騰訊>> 11.0
}
}