面向對象入門
基本概念
- 對象:①一切皆爲對象;②每個對象都是唯一的;③對象都屬於某個類;④對象都有屬性和行爲。
- 類:類是將一類對象共同的特徵抽取出來的結果,是對象的藍圖和模板。
四大支柱
- 抽象(abstraction):尋找共性。定義類的過程就是一個抽象的過程,需要做數據抽象和行爲抽象。
- 封裝(encapsulation):隱藏一切可以隱藏的複雜繁瑣的實現細節,只提供清晰簡單的接口(界面)。
- 繼承(inheritance):從已有的類創建新類的過程。提供繼承信息的類叫父類(超類、基類),得到繼承信息的類叫子類(派生類、衍生類)。
- 多態(polymorphism):執行相同的行爲卻做了不同的事情(產生了不同的結果)。
定義類
創建和使用對象
發現問題域中的類
從問題描述中找名詞和動詞,名詞會成爲類或者對象的屬性,動詞會成爲對象的方法。
類的結構
public class 類名 {
// 屬性(數據抽象)
// 構造器
// 方法(行爲抽象)
}
創建和使用對象的語法
類型 變量名 = new 構造器([參數列表]);
變量名.方法([參數列表]);
練習1:寫一個類,模擬數字時鐘。
package com.lovoinfo;
import java.util.Calendar;
/**
* 時鐘
* @author jackfrued
*
*/
public class Clock {
private int hour; // 時
private int minute; // 分
private int second; // 秒
/**
* 構造器
*/
public Clock() {
Calendar cal = Calendar.getInstance();
hour = cal.get(Calendar.HOUR_OF_DAY);
minute = cal.get(Calendar.MINUTE);
second = cal.get(Calendar.SECOND);
}
/**
* 構造器
* @param hour 時
* @param minute 分
* @param second 秒
*/
public Clock(int hour, int minute, int second) {
this.hour = hour;
this.minute = minute;
this.second = second;
}
/**
* 走字
*/
public void go() {
second += 1;
if(second == 60) {
second = 0;
minute += 1;
if(minute == 60) {
minute = 0;
hour += 1;
if(hour == 24) {
hour = 0;
}
}
}
}
/**
* 顯示時間
* @return 返回當前時間
*/
public String display() {
String str = "";
if(hour < 10) {
str += "0";
}
str += hour + ":";
if(minute < 10) {
str += "0";
}
str += minute + ":";
if(second < 10) {
str += "0";
}
str += second;
return str;
}
/**
* 調整小時
* @param up true表示上調, false表示下調
*/
public void setHour(boolean up) {
if(up) {
hour = (hour + 1) % 24;
}
else {
hour -= 1;
if(hour == -1) {
hour = 23;
}
}
}
/**
* 調整分鐘
* @param up true表示上調, false表示下調
*/
public void setMinute(boolean up) {
if(up) {
minute = (minute + 1) % 60;
}
else {
minute -= 1;
if(minute == -1) {
minute = 59;
}
}
}
/**
* 調整秒
* @param up true表示上調, false表示下調
*/
public void setSecond(boolean up) {
if(up) {
second = (second + 1) % 60;
}
else {
second -= 1;
if(second == -1) {
second = 59;
}
}
}
}
package com.lovoinfo;
public class Test03 {
public static void main(String[] args) throws Exception {
Clock c = new Clock();
while(true) {
System.out.println(c.display());
Thread.sleep(1000);
c.go();
}
}
}
練習2:計劃修一個圓形的游泳池,半徑尚未確定,游泳池的外圍修建寬度爲3m的環形過道,過道的外圍修建一圈圍牆,已知圍牆的造價爲5元/m,過道的造價爲18元/m^2^,寫一個程序,輸入游泳池的半徑,計算出過道和圍牆的造價。
package com.lovoinfo;
// 1. 定義類(數據抽象[屬性]、行爲抽象[方法]、構造器)
/**
* 圓
* @author jackfrued
*
*/
public class Circle {
private double radius; // 半徑
/**
* 構造器
* @param radius 半徑
*/
public Circle(double radius) {
this.radius = radius;
}
/**
* 獲得周長
* @return 圓的周長
*/
public double circumference() {
return 2 * Math.PI * radius;
}
/**
* 獲得面積
* @return 圓的面積
*/
public double area() {
return Math.PI * radius * radius;
}
}
package com.lovoinfo;
import java.util.Scanner;
public class Test01 {
private static final double FUNIT = 5.5; // 圍牆的單位造價
private static final double CUNIT = 18; // 過道的單位造價
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入游泳池的半徑: ");
double r = sc.nextDouble();
// 2. 創建對象
Circle c1 = new Circle(r);
Circle c2 = new Circle(r + 3);
// 3. 讓對象發生行爲(對象調用方法)求解問題
System.out.printf("圍牆的造價爲: ¥%.2f元\n",
c2.circumference() * FUNIT);
System.out.printf("過道的造價爲: ¥%.2f元\n",
(c2.area() - c1.area()) * CUNIT);
sc.close();
}
}
練習3:學生類和老師類。
package com.lovoinfo;
/**
* 人(父類)
* @author jackfrued
*
*/
public class Person {
protected String name; // 姓名
protected int age; // 年齡
/**
* 構造器
* @param name 姓名
* @param age 年齡
*/
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 吃飯
*/
public void eat() {
System.out.println(name + "在吃飯");
}
/**
* 睡覺
*/
public void sleep() {
System.out.println(name + "在睡覺");
}
/**
* 玩耍
*/
public void play() {
}
}
package com.lovoinfo;
/**
* 學生(人的子類)
* @author jackfrued
*
*/
public class Student extends Person {
private String grade; // 年級
/**
* 構造器
* @param name 姓名
* @param age 年齡
* @param grade 年級
*/
public Student(String name, int age, String grade) {
super(name, age); // 調用父類構造器
this.grade = grade;
}
/**
* 學習
* @param courseName 課程名稱
*/
public void study(String courseName) {
System.out.println(name + "在學習" + courseName);
}
/**
* 玩耍(對父類中的play方法進行重新實現[重寫])
*/
public void play() {
System.out.println(name + "在玩LOL");
}
@Override
public String toString() {
return name + " - " + age + " - " + grade;
}
}
package com.lovoinfo;
/**
* 老師(人的子類)
* @author jackfrued
*
*/
public class Teacher extends Person {
private String title; // 職稱
/**
* 構造器
* @param name 姓名
* @param age 年齡
* @param title 職稱
*/
public Teacher(String name, int age, String title) {
super(name, age);
this.title = title;
}
/**
* 授課
* @param courseName 課程名稱
*/
public void teach(String courseName) {
System.out.println(name + "正在教" + courseName);
}
/**
* 玩耍(對父類中的play進行重新實現[重寫])
*/
public void play() {
System.out.println(name + "在打麻將");
}
@Override
public String toString() {
return name + " - " + age + " - " + title;
}
}
練習4:編程模擬銀行賬戶及其操作。
package com.lovoinfo;
/**
* 銀行賬戶
* @author jackfrued
*
*/
public class Account {
private String cardNumber; // 卡號
private String password; // 密碼
private double balance; // 餘額
/**
* 構造器
* @param cardNumber 卡號
* @param password 初始密碼
*/
public Account(String cardNumber, String password) {
this.cardNumber = cardNumber;
this.password = password;
this.balance = 0.0;
}
/**
* 驗證密碼
* @param thyPassword 輸入的密碼
* @return 驗證通過返回true否則返回false
*/
public boolean verify(String thyPassword) {
return password.equals(thyPassword);
}
/**
* 取款
* @param money 取款金額
* @return 取款成功返回true否則返回false
*/
public boolean withdraw(double money) {
if(money > 0 && money <= balance) {
balance -= money;
return true;
}
return false;
}
/**
* 存款
* @param money 存款金額
* @return 存款成功返回true否則返回false
*/
public boolean deposit(double money) {
if(money > 0) {
balance += money;
return true;
}
return false;
}
/**
* 轉賬
* @param other 轉入賬戶
* @param money 轉出金額
* @return 轉賬成功返回true否則返回false
*/
public boolean transfer(Account other, double money) {
if(this.withdraw(money)) { // 如果當前賬戶扣款成功才能向轉入賬戶存錢
boolean flag = other.deposit(money);
if(!flag) { // 如果向轉入賬戶存錢不成功則應返還轉出金額
this.deposit(money);
}
return flag;
}
return false;
}
/**
* 查詢餘額
* @return 賬戶餘額
*/
public double getBalance() {
return balance;
}
/**
* 獲得卡號
* @return 卡號
*/
public String getCardNumber() {
return cardNumber;
}
/**
* 修改密碼
* @param newPassword 新密碼
*/
public void changePassword(String newPassword) {
this.password = newPassword;
}
}
練習5:雙色球隨機選號程序。
package com.lovoinfo;
/**
* 球
* @author jackfrued
*
*/
public class Ball {
private int number; // 數字
private boolean used; // 是否被使用過
/**
* 構造器
* @param number 球上面的數字
*/
public Ball(int number) {
this.number = number;
// this.used = false;
}
/**
* 球是否被使用過
* @return 使用過返回true否則返回false
*/
public boolean isUsed() {
return used;
}
/**
* 設置球有沒有被使用過
* @param used true表示使用過false表示沒有使用過
*/
public void setUsed(boolean used) {
this.used = used;
}
/**
* 獲得球上的號碼(如果號碼小於10前面要補0)
* @return 號碼補0後的字符串
*/
public String getNumber() {
return number < 10? "0" + number : "" + number;
}
/**
* 獲得球上的號碼
* @return 號碼的數字
*/
public int getNum() {
return number;
}
}
package com.lovoinfo;
/**
* 雙色球選號機
* @author jackfrued
*
*/
public class LotteryMachine {
private Ball[] redBalls = new Ball[33]; // 33個紅球
private Ball[] blueBalls = new Ball[16]; // 16個藍球
// 裝入紅色球和藍色球
public void load() {
for(int i = 0; i < redBalls.length; i++) {
redBalls[i] = new Ball(i + 1); // 創建一顆球
}
for(int i = 0; i < blueBalls.length; i++) {
blueBalls[i] = new Ball(i + 1);
}
}
// 搖出6個紅色球
public Ball[] getRedBalls() {
Ball[] rBalls = new Ball[6];
for(int i = 0; i < rBalls.length; i++) {
Ball currentBall = null;
do {
int index = (int) (Math.random() * redBalls.length);
currentBall = redBalls[index];
} while(currentBall.isUsed());
rBalls[i] = currentBall;
currentBall.setUsed(true);
}
for(int i = 1; i < rBalls.length; i++) {
for(int j = 0; j < rBalls.length - i; j++) {
if(rBalls[j].getNum() > rBalls[j + 1].getNum()) {
Ball temp = rBalls[j];
rBalls[j] = rBalls[j + 1];
rBalls[j + 1] = temp;
}
}
}
return rBalls;
}
// 搖出1個藍色球
public Ball getBlueBall() {
return blueBalls[(int) (Math.random() * blueBalls.length)];
}
// 產生一個隨機號碼
public String generateRandomNumber() {
load(); // 裝入紅色球和藍色球
Ball[] myRedBalls = getRedBalls(); // 搖出6個紅色球
Ball myBlueBall = getBlueBall(); // 搖出1個藍色球
String myNumber = "";
for(int i = 0; i < myRedBalls.length; i++) {
myNumber += myRedBalls[i].getNumber() + " ";
}
myNumber += "|";
myNumber += " " + myBlueBall.getNumber();
return myNumber;
}
}
package com.lovoinfo;
import java.util.Scanner;
public class Test06 {
public static void main(String[] args) {
LotteryMachine lm = new LotteryMachine();
Scanner sc = new Scanner(System.in);
System.out.print("機選幾注: ");
int n = sc.nextInt();
for(int i = 1; i <= n; i++) {
System.out.println(lm.generateRandomNumber());
}
sc.close();
}
}