-- 題目 1:定義一個類 Person
-- 屬性:name、age,其中 age 默認是 0,不能小于 0。
-- 方法:introduce(),輸出 "My name is <name>, I am <age> years old."
-- 要求使用封裝思想,age 設置必須通過一個方法 setAge(age),并在方法中處理合法性。
local Person = {} Person.__index = Person--構造函數 function Person:new(name, age)local obj = {name = name or "UnKnow",age = 0,}setmetatable(obj,self)obj:setAge(age)return obj endfunction Person:introduce()print("My name is "..self.name..", I am "..self.age.." years old.") endfunction Person:setAge(age)if (age and type(age) == "number" and age > 0) thenself.age = ageelseprint("[Warning] Invalid age value, defaulting to 0.")end end
-- 題目 2:類中添加私有方法(模擬私有函數)
-- 在 Person 類中,添加一個私有函數 calculateBirthYear(currentYear),根據年齡推算出生年份。
-- 在 introduce() 中調用它,輸出內容增加一句:"I was born in <year>."
-- 提示:Lua 本身沒有私有函數機制,但可以通過 local 函數模擬。
local function calculateBirthYear(self, currentYear)return currentYear - self.age endfunction Person:introduce()print("My name is "..self.name..", I am "..self.age.." years old.")print("I was born in "..calculateBirthYear(self, 2025)..".") endlocal o = Person:new("Keixo",12) o:introduce()
-- 題目 3:定義子類 Student 繼承 Person
-- 除了繼承的屬性和方法外,還新增屬性 school,方法 introduce() 要重寫,輸出:
-- My name is <name>, I am <age> years old.
-- I study at <school>.
-- 同時添加方法 study(subject),輸出:"<name> is studying <subject>."
local Student = {} Student.__index = Student setmetatable(Student, {__index = Person})function Student:new(name, age, school)local obj = Person.new(self, name, age)-- setmetatable(obj, self)obj.school = school or "UnKnow School"return obj endfunction Student:introduce()print("My name is "..self.name..", I am "..self.age.." years old.")print("I study at "..self.school..".") endfunction Student:study(subject)print(self.name.." is studying "..subject..".") endlocal u = Student:new("Z",-2, "nihao") u:introduce() u:study("Math")
-- 題目 4:定義子類 Teacher 繼承 Person
-- 屬性:subject,
-- 方法:teach() 輸出:"<name> is teaching <subject>."
-- 并重寫 introduce() 輸出:
-- My name is <name>, I am <age> years old.
-- I teach <subject>.
local Teacher = {} Teacher.__index = Teacher setmetatable(Teacher, {__index = Person})function Teacher:new(name, age, subject)local obj = Person.new(self,name, age)obj.subject = subject-- setmetatable(obj, self)return obj endfunction Teacher:teach()print(self.name.."is teaching "..self.subject..".")print("I teach "..self.subject..".") endlocal y = Teacher:new("y", 20, "Math") y:introduce() y:teach()
-- 題目 5:實現一個多態接口 introduceAll
-- 定義一個函數 introduceAll(personList),參數是一個表,內部調用每個人的 introduce() 方法。
-- 傳入 Person、Student、Teacher 等不同對象,驗證其輸出是否符合多態行為。
local function introduceAll(personList)for i, person in ipairs(personList) doperson:introduce()end endlocal people = {Person:new("p",1),Student:new("s",2),Teacher:new("t",3) }introduceAll(people)
-- 題目 6:添加“靜態方法”支持
-- 給 Person 添加一個類方法(靜態方法)isAdult(age),返回是否大于等于 18 歲。
-- 提示:通過 Person.isAdult = function(age) ... end 實現。
Person.isAdult = function(age)return (type(age) == "number" and age >= 18) and true or false endprint(o.isAdult(9))
-- 題目 7:模擬構造函數重載
-- 修改 Person:new(),支持兩種構造方式:
-- Person:new(name, age)
-- Person:new({name = "xx", age = xx})
-- 要求兩種方式都能成功創建對象。
function Person:new(nameOrTable, age)local obj = {}if type(nameOrTable) == "table" thenfor i,v in pairs(nameOrTable) doobj[i] = vendelseif type(nameOrTable) == "string" thenobj.name = nameOrTableobj.age = ageendsetmetatable(obj,self)return obj endlocal p = Person:new("p", 12) local k = Person:new({name = "k", age = 12})p:introduce() k:introduce()