今日內容
-
面向對象複習
-
面向對象練習
教學目標
- 能夠完成面向對象練習1
- 能夠完成面向對象練習2
- 能夠完成面向對象練習3
- 能夠完成面向對象練習4
- 能夠完成面向對象練習5
- 能夠完成面向對象練習6
- 能夠完成面向對象練習7
第一章 面向對象複習
1.1 如何定義類
類的定義格式如下:
修飾符 class 類名{
// 1.成員變量(屬性)
// 2.成員方法 (行爲)
// 3.構造器 (初始化類的對象數據的)
}
例如:
public class Student {
// 1.成員變量
public String name;
public char sex; // '男' '女'
public int age;
public void eat() {
System.out.println(name + "在喫飯");
}
}
1.2 如何通過類創建對象
類名 對象名稱 = new 類名();
例如:
Student stu = new Student();
1.3 封裝
封裝的步驟
1.使用 private
關鍵字來修飾成員變量。
2.使用public
修飾getter和setter方法。
封裝的實現
- private修飾成員變量
public class Student {
private String name;
private int age;
}
- public修飾getter和setter方法
public class Student {
private String name;
private int age;
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public void setAge(int a) {
if (a > 0 && a <200) {
age = a;
} else {
System.out.println("年齡非法!");
}
}
public int getAge() {
return age;
}
}
1.4 構造方法
構造方法的作用
完成對象數據的初始化。
構造方法的格式
public class 類名 {
修飾符 類名(參數) {
}
}
構造方法的應用
首先定義一個學生類,代碼如下:
public class Student {
// 1.成員變量
public String name;
public int age;
// 2.構造器
public Student() {
System.out.println("無參數構造器被調用");
}
}
接下來通過調用構造器得到兩個學生對象。
public class CreateStu02 {
public static void main(String[] args) {
// 創建一個學生對象
// 類名 變量名稱 = new 類名();
Student s1 = new Student();
// 使用對象訪問成員變量,賦值
s1.name = "張三";
s1.age = 20 ;
// 使用對象訪問成員變量 輸出值
System.out.println(s1.name);
System.out.println(s1.age);
Student s2 = new Student();
// 使用對象訪問成員變量 賦值
s2.name = "李四";
s2.age = 18 ;
System.out.println(s2.name);
System.out.println(s2.age);
}
}
1.5 this關鍵字的作用
this關鍵字的作用
this代表所在類的當前對象的引用(地址值),即代表當前對象。
this關鍵字的應用
用於普通的gettter與setter方法
this出現在實例方法中,誰調用這個方法(哪個對象調用這個方法),this就代表誰(this就代表哪個對象)。
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
if (age > 0 && age < 200) {
this.age = age;
} else {
System.out.println("年齡非法!");
}
}
public int getAge() {
return age;
}
}
用於構造方法中
this出現在構造器中,代表構造器正在初始化的那個對象。
public class Student {
private String name;
private int age;
// 無參數構造方法
public Student() {}
// 有參數構造方法
public Student(String name,int age) {
this.name = name;
this.age = age;
}
}
1.6 繼承
繼承格式
通過 extends
關鍵字,可以聲明一個子類繼承另外一個父類,定義格式如下:
class 父類 {
...
}
class 子類 extends 父類 {
...
}
繼承好處
- 提高代碼的複用性(減少代碼冗餘,相同代碼重複利用)。
- 使類與類之間產生了關係。
1.7 抽象
抽象方法
使用abstract
關鍵字修飾方法,該方法就成了抽象方法,抽象方法只包含一個方法名,而沒有方法體。
定義格式:
修飾符 abstract 返回值類型 方法名 (參數列表);
代碼舉例:
public abstract void run();
抽象類
如果一個類包含抽象方法,那麼該類必須是抽象類。
定義格式:
abstract class 類名字 {
}
代碼舉例:
public abstract class Animal {
public abstract void run();
}
1.8 final關鍵字
final: 不可改變。可以用於修飾類、方法和變量。
- 類:被修飾的類,不能被繼承。
- 方法:被修飾的方法,不能被重寫。
- 變量:被修飾的變量,不能被重新賦值。
修飾類
final class 類名 {
}
修飾方法
修飾符 final 返回值類型 方法名(參數列表){
//方法體
}
修飾變量
final 數據類型 變量名
1.9 static關鍵字
修飾變量
static修飾的成員被多個對象共享。
static 數據類型 變量名;
修飾方法
修飾符 static 返回值類型 方法名 (參數列表){
// 執行語句
}
被static修飾的成員可以並且建議通過類名直接訪問。
1.10 接口
接口的內部主要就是封裝了方法,包含抽象方法(JDK 7及以前),默認方法和靜態方法(JDK 8)。
定義格式
public interface 接口名稱 {
// 抽象方法
// 默認方法
// 靜態方法
}
類實現接口
class 類名 implements 接口名 {
// 重寫接口中抽象方法【必須】
// 重寫接口中默認方法【可選】
}
1.11 匿名對象【理解】
概念
需求:
1、創建一個學生的類Student,並在Student類中定義兩個屬性name和age。
2、在Student類中定義一個函數demo()。
3、定義一個測試學生類的類StudentTest。
Student:是一個類。描述的是學生這個事物
student:類所創建的對象名(實例名)
匿名對象:就是指沒有名稱的對象。創建對象時,只有創建對象的語句,卻沒有把對象地址值賦值給某個變量。雖然是創建對象的簡化寫法,但是應用場景非常有限。
格式:
new 類名(參數列表);
舉例:
new Scanner(System.in);
new Student();
匿名對象應用場景
說明:匿名對象是指創建對象時,只有創建對象的語句,卻沒有把對象地址值賦值給某個變量。
匿名對象的侷限性
上述代碼結果:
null 學習中。。。。。
出現以上問題的原因如下圖所示:
注意:只要在程序中使用new關鍵字創建對象,那麼在堆中都會有一個新的對象產生。
注意:匿名對象通常是在對象只需要訪問成員一次的情況下使用
如果對象需要多次的操作成員,就不能使用匿名對象來訪問。
注意:匿名對象可以簡化代碼的書寫,但是匿名對象一旦使用結束,這時這個對象就立刻變成垃圾。
如果對象只使用一次,這時可以採用匿名對象,如果這個對象要使用多次,必須給對象起名。
匿名對象作爲參數傳遞(理解)
需求:
1)定義一個Person類,在這個類中定義人的名字和年齡,並定義一個說話的功能;
2)再定義一個測試Person類的類PersonTest,在PersonTest類中定義一個功能,給所有的Person類的對象下的屬性name和age進行相同數據的賦值,並調用Person類中的說話的方法。
class Person
{
String name;
int age;
void say()
{
System.out.println(name+"哇哇哇哇叫"+age);
}
}
class PersonTest1
{
public static void main(String[] args)
{
//創建person對象
/*Person person =new Person();
demo(person);
Person person1 =new Person();
demo(person1);
Person person2 =new Person();
demo(person2);
上述程序中創建的Person對象的引用,僅僅是爲了把對象傳遞給demo函數,
這時也可以使用匿名對象傳遞對象
*/
demo(new Person());
}
/*
定義一個函數給Person類中的屬性賦值,並調用Person類中的方法
*/
public static void demo(Person p)//Person p=new Person();
{
p.name="baby";
p.age=1;
p.say();
}
}
第二章 面向對象練習
練習1
需求
定義一個撲克類Card
屬性:
- 花色
- 點數
構造方法:
- 滿參構造方法
成員方法:
- showCard方法:打印牌面信息
定義測試類
在main方法中使用滿參構造創建Card對象card,並調用showCard方法
代碼實現,效果如圖所示:
案例代碼
Card類
public class Card {
private String ds; // 點數
private String hs; // 花色
public Card(String ds, String hs) {
this.ds = ds;
this.hs = hs;
}
public void showCard() {
System.out.println(ds + hs);
}
}
測試類
public class Test02 {
public static void main(String[] args) {
Card card = new Card("A","黑桃");
card.showCard();
}
}
練習2
需求
-
定義兩個類,經理類Manager,程序員類Coder
-
Coder類:
- 屬性:姓名,工號,薪資
- 構造方法:無參和滿參構造方法
- 成員方法:
- intro方法:打印姓名,工號信息
- showSalary方法:打印薪資信息
- work方法:打印"正在努力寫代碼…"
-
Manager類:
- 屬性:姓名,工號,薪資,獎金
- 構造方法:無參和滿參構造方法
- 成員方法:
- intro方法:打印姓名,工號信息
- showSalary方法:打印薪資和獎金信息
- work方法:打印"正在努力的做着管理工作,分配任務,檢查員工提交上來的代碼…"
-
定義測試類,創建Manager對象,創建Coder對象,並測試
-
代碼實現,效果如圖所示:
案例代碼
Coder類
public class Coder {
String name;
String id;
int salary; // 基本工資
public Coder() {
}
public Coder(String name, String id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public void showSalary() {
System.out.println("基本工資爲" + salary + ",獎金無");
}
public void intro() {
System.out.println("程序員姓名:" + name);
System.out.println("工號:" + id);
}
public void work() {
System.out.println("正在努力寫代碼....");
}
}
Manager類
public class Manager {
String name;
String id;
int salary; // 基本工資
int bouns; // 獎金
public Manager() {
}
public Manager(String name, String id, double salary, double bonus) {
this.name = name;
this.id = id;
this.salary = salary;
this.bonus = bonus;
}
public void showSalary() {
System.out.println("基本工資爲" + salary + ",獎金爲" + bouns);
}
public void intro() {
System.out.println("經理姓名:" + name);
System.out.println("工號:" + id);
}
public void work() {
System.out.println("正在努力的做着管理工作,分配任務,檢查員工提交上來的代碼.....");
}
}
測試類
public class Test02 {
public static void main(String[] args) {
Manager m = new Manager("James","9527",15000,3000);
m.intro();
m.showSalary();
m.work();
System.out.println("============");
Coder c = new Coder("Kobe","0025",10000);
c.intro();
c.showSalary();
c.work();
}
}
練習3
需求
請使用繼承定義以下類:
程序員(Coder)
成員變量: 姓名,年齡
成員方法: 喫飯,睡覺,敲代碼
老師(Teacher)
成員變量: 姓名,年齡
成員方法: 喫飯,睡覺,上課
將程序員和老師中相同的內容(姓名,年齡,喫飯,睡覺)抽取到父類Person中
效果如圖所示:
案例代碼
Person類
public class Person {
String name;
int age;
public void eat() {
System.out.println(name + "喫飯");
}
public void sleep() {
System.out.println(name + "睡覺");
}
}
Coder類
public class Coder extends Person {
// 敲代碼
public void coding() {
System.out.println(name + "敲代碼");
}
}
Teacher類
public class Teacher extends Person {
public void teach() {
System.out.println(name + "上課");
}
}
測試類
public class Test03 {
public static void main(String[] args) {
// 創建Code對象,並設置成員變量的值
Coder c = new Coder();
c.name = "馬化騰";
c.age = 45;
// 調用Coder對象的eat()方法
c.eat();
// 調用Coder對象的sleep()方法
c.sleep();
// 調用Coder對象的coding()方法
c.coding();
System.out.println("-----------");
// 創建Teacher對象,並設置成員變量的值
Teacher t = new Teacher();
t.name = "馬雲";
t.age = 50;
// 調用Teacher對象的eat()方法
t.eat();
// 調用Teacher對象的sleep()方法
t.sleep();
// 調用Teacher對象的teach()方法
t.teach();
}
}
練習4
需求
請使用繼承
,抽象方法
,抽象類
定義以下類:
1.經理
成員變量:工號,姓名,工資
成員方法:工作(管理其他人),喫飯(喫魚)
2.廚師
成員變量:工號,姓名,工資
成員方法:工作(炒菜),喫飯(喫肉)
說明:雖然經理和廚師都有工作和喫飯的行爲,但是工作方式和喫的內容是不一樣的,所以需要抽取父類員工類中,並且變爲抽象類。
效果如圖所示:
案例代碼
抽象的Employee類
abstract class Employee {
// 工號屬性,姓名屬性,工資屬性
private String id;
private String name;
private double salary;
public Employee() {
}
public Employee(String id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
// 抽象的工作方法
public abstract void work();
// 抽象的喫飯方法
public abstract void eat();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
Manager類
// 經理繼承員工,重寫工作方法,和喫飯方法
class Manager extends Employee {
public Manager() {
}
public Manager(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("工號爲:" + getId() + ",姓名爲:" + getName() + "工資爲:" + getSalary() + "的經理在工作,管理其他人");
}
@Override
public void eat() {
System.out.println("工號爲:" + getId() + ",姓名爲:" + getName() + "工資爲:" + getSalary() + "的經理在喫魚");
}
}
Cook類
class Cook extends Employee {
public Cook() {
}
public Cook(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("工號爲:" + getId() + ",姓名爲:" + getName() + "工資爲:" + getSalary() + "的廚師在工作,炒菜");
}
@Override
public void eat() {
System.out.println("工號爲:" + getId() + ",姓名爲:" + getName() + "工資爲:" + getSalary() + "的廚師在喫肉");
}
}
測試類
public class Test04 {
public static void main(String[] args) {
// 創建Manager對象
Manager m = new Manager("m110", "老王", 10000);
// 調用Manager對象的eat方法
m.eat();
// 調用Manager對象的work方法
m.work();
// 創建Cook對象
Cook c = new Cook("c110", "小王", 6000);
// 調用Cook對象的eat方法
c.eat();
// 調用Cook對象的work方法
c.work();
}
}
練習5
需求
請使用繼承
,抽象方法
,抽象類
定義以下類:
1.在傳智播客有很多員工(Employee),按照工作內容不同分教研部員工(Teacher)和行政部員工(AdminStaff)
2.教研部根據教學的方式不同又分爲講師(Lecturer)和助教(Tutor)
3.行政部根據負責事項不同,又分爲維護專員(Maintainer),採購專員(Buyer)
4.公司的每一個員工都有編號,姓名和其負責的工作
5.每個員工都有工作的功能,但是具體的工作內容又不一樣,在向上抽取的時候定義爲抽象方法
效果如圖所示:
類之間的關係如下:
案例代碼
Employee類
/*
1.定義抽象類員工類(Employee)
a)成員變量: 工號(id),姓名(name)
b)抽象方法: void work();
c)提供無參和帶參的構造方法以及setters和getters
*/
public abstract class Employee {
// a)成員變量: 工號(id),姓名(name)
private String id;
private String name;
// b)抽象方法: void work();
public abstract void work();
// c)提供無參和帶參的構造方法以及setters和getters
public Employee() {
super();
}
public Employee(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Teacher類
/*
2.定義抽象類教研部員工(Teacher)類繼承員工類(Employee)
*/
public abstract class Teacher extends Employee{
// a)提供無參和帶參的構造方法
public Teacher() {
super();
}
public Teacher(String id, String name) {
super(id, name);
}
}
AdminStaff類
/*
3.定義抽象類行政部員工(AdminStaff)類繼承員工類(Employee)
*/
public abstract class AdminStaff extends Employee {
// a)提供無參和帶參的構造方法
public AdminStaff() {
super();
}
public AdminStaff(String id, String name) {
super(id, name);
}
}
Lecturer類
/*
4.定義講師(Lecturer)類繼承研部員工(Teacher)類
*/
public class Lecturer extends Teacher {
// a)提供無參和帶參的構造方法
public Lecturer() {
super();
}
public Lecturer(String id, String name) {
super(id, name);
}
// b)實現抽象方法: void work();
// 輸出格式: 工號爲 666 的講師 傅紅雪 在講課
public void work() {
System.out.println("工號爲 "+getId()+" 的講師 "+getName()+" 在講課");
}
}
Tutor類
/*
5.定義助教(Tutor)類繼承研部員工(Teacher)類
*/
public class Tutor extends Teacher{
// a)提供無參和帶參的構造方法
public Tutor() {
super();
}
public Tutor(String id, String name) {
super(id, name);
}
// b)實現抽象方法: void work();
// i.輸出格式: 工號爲 668的助教 顧棋 在幫助學生解決問題
public void work() {
System.out.println("工號爲 "+getId()+"的助教 "+getName()+" 在幫助學生解決問題");
}
}
Maintainer類
/*
6.定義維護專員(Maintainer)類繼承行政部員工(AdminStaff)類
*/
public class Maintainer extends AdminStaff {
// a)提供無參和帶參的構造方法
public Maintainer() {
super();
}
public Maintainer(String id, String name) {
super(id, name);
}
// b)實現抽象方法: void work();
// i.輸出格式: 工號爲 686 的維護專員 庖丁 在解決不能共享屏幕問題
public void work() {
System.out.println("工號爲 "+getId()+" 的維護專員 "+getName()+" 在解決不能共享屏幕問題");
}
}
Buyer類
/*
7.定義採購專員(Buyer) 類繼承行政部員工(AdminStaff)類
*/
public class Buyer extends AdminStaff {
// a)提供無參和帶參的構造方法
public Buyer() {
super();
}
public Buyer(String id, String name) {
super(id, name);
}
// b)實現抽象方法: void work();
// 輸出格式: 工號爲 888 的採購專員 景甜 在採購音響設備
public void work() {
System.out.println("工號爲 "+getId()+" 的採購專員 "+getName()+" 在採購音響設備");
}
}
測試類
/*
8.定義測試類Test
*/
public class Test5 {
public static void main(String[] args) {
// a)創建講師對象l, 把工號賦值爲666,姓名賦值爲”傅紅雪”
Lecturer l = new Lecturer("666", "傅紅雪");
// b)調用講師對象l的工作方法
l.work();
// c)創建助教對象 t, 把工號賦值爲668,姓名賦值爲”顧棋”
Tutor t = new Tutor("668", "顧棋");
// d)調用助教對象t的工作方法
t.work();
// e)創建維護專員對象 m, 把工號賦值爲686,姓名賦值爲”庖丁”
Maintainer m = new Maintainer("686", "庖丁");
// f)調用維護專員對象m的工作方法
m.work();
// g)創建採購專員對象 b, 把工號賦值爲888,姓名賦值爲”景甜”
Buyer b = new Buyer("888", "景甜");
// h)調用採購專員對象b的工作方法
b.work();
}
}
練習6
需求
請使用繼承
,接口
,定義以下類:
兩個手機類OldPhone和NewPhone都有call()和sendMessage()方法.定義接口Play,Play中有一個抽象的玩遊戲的方法playGame(),NewPhone繼承舊手機類OldPhone並實現Play接口有玩遊戲的功能;
要求:
分別測試OldPhone和NewPhone的call()和sendMessage()方法,再測試新手機palyGame()的方法
效果如圖所示:
案例代碼
Play接口
// 1.定義接口Play
interface Play {
// 2.在Play中定義一個抽象的玩遊戲的方法playGame()
public abstract void playGame();
}
OldPhone類
// 3.定義OldPhone類
class OldPhone {
// 4.在OldPhone類中定義call()和sendMessage()方法
public void call() {
System.out.println("舊手機打電話");
}
public void sendMessage() {
System.out.println("舊手機發短信");
}
}
NewPhone類
// 5.定義NewPhone類,繼承OldPhone,實現Play接口
class NewPhone extends OldPhone implements Play {
@Override
public void playGame() {
System.out.println("新手機玩遊戲");
}
@Override
public void call() {
System.out.println("新手機打電話");
}
@Override
public void sendMessage() {
System.out.println("新手機發短信");
}
}
測試類
public class Test06 {
public static void main(String[] args) {
// 6.創建舊手機對象
OldPhone oldPhone = new OldPhone();
// 7.使用舊手機打電話
oldPhone.call();
// 8.使用舊手機發信息
oldPhone.sendMessage();
// 9.創建新手機對象
NewPhone newPhone = new NewPhone();
// 10.使用新手機打電話
newPhone.call();
// 11.使用新手機發信息
newPhone.sendMessage();
// 12.使用新手機玩遊戲
newPhone.playGame();
}
}
練習7
需求
請使用繼承
,接口
,定義以下類:
學生都有年齡和姓名屬性,有喫飯(學生餐)和學習方法,但是有部分學生會打籃球
老師都有年齡和姓名屬性,有喫飯(工作餐)和講課方法,但是有部分老師會打籃球
定義一個方法模擬去打籃球,只要會打籃球的人都可以傳入. (提示通過在測試類中定義一個方法參數爲接口)
效果如圖所示:
類和接口之間的關係如下:
案例代碼
抽象的Person類
// 1.定義Person類
abstract class Person {
// 2.Person類包含name,age屬性和抽象的eat方法
private String name;
private int age;
public abstract void eat();
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = 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;
}
}
Sport接口
// 3.定義Sport接口,包含playBasketball方法
interface Sport {
public abstract void playBasketball();
}
Teacher類
// 4.定義Teacher類繼承Person類,重寫抽象方法eat()
class Teacher extends Person {
public void eat() {
System.out.println();
}
public void teach() {
System.out.println(getName() + "老師在講課");
}
public Teacher() {
super();
}
public Teacher(String name, int age) {
super(name, age);
}
}
SportTeacher類
// 5.定義SportTeacher類繼承Teacher類,實現Sport接口,重寫Sport接口中的playBasketball方法
class SportTeacher extends Teacher implements Sport {
public void playBasketball() {
System.out.println("年齡爲" + getAge() + "歲 " + getName() + " 的老師在打籃球");
}
public SportTeacher() {
super();
}
public SportTeacher(String name, int age) {
super(name, age);
}
}
Student類
// 6.定義Student類繼承Person類,重寫抽象方法eat()
class Student extends Person {
public void eat() {
System.out.println("年齡" + getAge() + "歲的 " + getName() + " 在喫學生餐");
}
public void study() {
System.out.println(getName() + "學生在學習");
}
public Student() {
super();
}
public Student(String name, int age) {
super(name, age);
}
}
SportStudent類
// 7.定義SportStudent類繼承Student類,實現Sport接口,重寫Sport接口中的playBasketball方法
class SportStudent extends Student implements Sport {
public SportStudent() {
}
public SportStudent(String name, int age) {
super(name, age);
}
public void playBasketball() {
System.out.println("年齡爲" + getAge() + "歲 " + getName() + " 的學生在打籃球");
}
}
測試類
public class Test07 {
public static void main(String[] args) {
// 9.在main方法中創建普通的老師t1,姓名爲馬雲,年齡爲45歲
Teacher t1 = new Teacher("馬雲", 45);
// 10.在main方法中創建會打籃球的老師t2,姓名爲大姚,年齡爲35歲
SportTeacher t2 = new SportTeacher("大姚", 35);
// 11.在main方法中創建普通的學生s1,姓名爲小王,年齡爲20
Student s1 = new Student("小王", 20);
// 12.在main方法中創建會打籃球的學生s2,姓名爲王中王,年齡爲21
SportStudent s2 = new SportStudent("王中王", 21);
// 13.在main方法中調用goToSport方法.傳入t1,t2,s1,s2四個對象.我們會發現只有實現Sport接口的對象才能傳入
// goToSport(t1); // 沒有實現Sport接口不能傳入
goToSport(t2);
// goToSport(s1); // 沒有實現Sport接口不能傳入
goToSport(s2);
}
// 8.在測試類中定義靜態的goToSport方法,參數爲Sport接口類型
public static void goToSport(Sport s){
// 在goToSport方法中調用傳入參數的playBasketball方法
s.playBasketball();
}
}