接下来算是小聊一下 Python 的 Class 语法而已,算是稍微休息一下,所以这边简单聊就好。
Python 本身就是一个物件导向语言(Object-oriented programming,就是俗称的 OOP),那麽什麽是物件导向呢?JavaScript 也是物件导向语言吗?
好吧,这个问题其实困扰我很久,所以前面就稍微简单聊一下这个东西,毕竟有些人说 JavaScript 是物件导向语言也有人家说 JavaScript 不是物件导向的语言,那麽到底什麽是物件导向呢?与其绕口令不如翻一些文件来说明,先让我们看一下维基百科对於「物件导向程序设计」的解释是什麽:
它可能包含资料、特性、程序码与方法。物件则指的是类别(class)的实例。它将物件作为程序的基本单元,将程序和资料封装其中,以提高软件的重用性、灵活性和扩充性,物件里的程序可以存取及经常修改物件相关连的资料。在物件导向程序程序设计里,电脑程序会被设计成彼此相关的物件。
相信这边你应该看得非常混淆,毕竟描述的很文邹邹:
但是你可能会想说「物件导向,那这个是不是跟物件有关系啊?」
答案是「没错,确实有关系」,就是与物件有很大的关联性,除此之外通常物件导向的开发会是以一个类别去做宣告,也就是 class
,而这个 class
通常是一个抽象的物件,举例来讲会有一个狗的类别,然这个狗的类别会具有牠所有的基本特徵,所以写法可能是这样:
class 狗
public 方法:
吼叫()
指甲:
private 方法:
毛色:
品种:
尾巴长度:
名字:
学名:
(我绝对不会说我是看着我家的狗在想上面的 class)
而我们可以透过上面的狗类别一直继承下来给予其他特有的名称,例如:毛色是棕色、品种是米克斯、尾巴无等等,所以你可以把物件导向也想像成它是一个蓝图概念。
依照上面的说法来讲,所以 JavaScript 也是物件导向语言罗?答案基本上是的,JavaScript 确实也是物件导向语言,但是 JavaScript 是以 原型基础为导向 的物件导向语言,我相信你看到这边已经感觉像是绕口令了,所以接下来就来看一些范例好了。
以下是 Java 语言,我随便简单写出来参考比较而已:
class Home
{
public String father;
public String mother;
Home(String a, String b) {
father = a;
mother = b;
}
public void myFather(){
System.out.println("my father is " + father);
}
}
public class main
{
public static void main(String[] args)
{
Home myHome = new Home("jack", "judy");
System.out.println(myHome.father); // jack
System.out.println(myHome.mother); // mother
myHome.myFather(); // my father is jack
}
}
但是如果将上面程序码改写成 JavaScript 的话则是以下:
function Home(father, mother) {
this.father = father;
this.mother = mother;
}
Home.prototype.myFather = function() {
console.log('my father is ' + this.father);
}
const myHome = new Home('Jack', 'Judy');
console.log(myHome.father, myHome.mother);// Jack Judy
myHome.myFather(); // my father is jack
至於为什麽挑 Java 当作范例就不多说明了(笑)。
基本上我们可以看到 Java 就是以 class
去抽象化一个东西、一个概念,而这个 class
可以一直被继承。
但是前面范例中我们也有看到 JavaScript 也可以做到类似的事情,难道这样子 JavaScript 还不算是一个物件导向语言吗?事实上 JavaScript 不太适合直接说它是 OOP,而是比较适合叫 OOJS(Object-oriented JavaScript),毕竟 JavaScript 是以原型为基础的语言,详情可以在阅读 MDN 文件中的 初学者应知道的物件导向 JavaScript 章节会有更好的描述,而前面这边只是小小的简单聊一下而已,并没有打算过度深入谈论这一块。
oh!题外话一下,虽然 JavaScript 在 ECMAScript6 引入了 class
语法,但本质上那只是 prototype
的语法糖而已,实际上 JavaScript 在底层的运作依然是属於原型,千万不要被 JavaScript 的 class
语法糖给骗了唷~
前面有提到 Python 本身就是一个 OOP 语言也有讲到什麽是物件导向的概念之後,接下来我们也要来认识一下 Python 要如何建立属於自己的 class
,有写过 JavaScript class
语法的人基本上会感觉很熟悉或者格外亲切,因为语法上的使用非常的雷同:
class Home:
father = 'jack'
这边我们也可以简单看一下 JavaScript 的 class
:
class Home {
father = 'jack'
}
是不是觉得两者相似度很高呢?感到格外亲切了呢?
那麽 Python 该如何实例化刚刚宣告的 class 呢?你不知道什麽是实例化吗?简单来讲你可以把它当作你给了这个抽象的东西一个生命的概念,所以让我们来看一下怎麽该实例化:
class Home:
father = 'jack'
myHome = Home()
print(myHome.father) # jack
有没有觉得超级简单呢?连 new
都省略了呢!是不是觉得超级简洁呢?(JavaScript 必须使用 new
才可以。)
但是这时候你可以会想说建立一个 class
的时候,我们都会需要传入一些参数告知目前 class
的一些初始值或者样貌,以狗来举例的话,你给予狗生命时总要给牠毛色与品种吧?
那麽以 JavaScript 的写法来讲的话就会像这样:
class Home {
constructor(father) {
this.father = father;
}
}
const myHome = new Home('jack');
console.log(myHome.father); // jack
那麽 Python 呢?Python 也是用 constructor
吗?Python 主要是用 __init__
函式,所有的 class
都会有一个 __init__
,就跟 JavaScript 一样,所有的 class
都有一个 constructor
可以使用,所以写法就会变成以下:
class Home:
def __init__ (self, father):
self.father = father
myHome = Home('jack')
print(myHome.father) # jack
此刻的你应该会觉得很疑惑 __init__
中的 self
是什麽东西?你可以把它想像成 JavaScript 中 constructor
的 this
,但是千万不要把 Python 中的 self
跟 JavaScript 的 self
搞混,刚好前阵子我有写一篇关於 JavaScript 的 self
是什麽的文章,也推荐给你参考看看。
好,拉回 Python 中,所以 Python 的 self
会指向 class Home
本身,而每次建立一个 class
的时候,Python 都会自动呼叫 __init__
函式(JavaScript 也是相同的,它会自动呼叫 constructor
函式)基本上你也不一定要宣告为 self
你也可以叫别的,例如:hello
or ray
等等:
class Home:
def __init__ (ray, father):
ray.father = father
myHome = Home('jack')
print(myHome.father) # jack
但是我建议还是保留叫 self
会比较好,如果你取名一个很奇怪的名字,可能会被约出去喝咖啡。
那麽接下来也是与 Java 类似,我们会将函式方法写在 class
中,但是这边要注意,请记得替该方法传入 self
,否则你会无法呼叫 class
本身的属性:
class Home:
def __init__ (self, father):
self.father = father
def myFather(self):
print('my father is ' + self.father)
myHome = Home('jack')
print(myHome.father) # jack
myHome.myFather() # my father is jack
当如果你想修改 Home 中的属性的话,也非常的简单,就跟修改物件属性的方式相同:
class Home:
def __init__ (self, father):
self.father = father
def myFather(self):
print('my father is ' + self.father)
myHome = Home('jack')
print(myHome.father) # jack
myHome.myFather() # my father is jack
myHome.father = 'Ray'
print(myHome.father) # Ray
其他的还有删除 class 中的属性与方法等等:
class Home:
def __init__ (self, father):
self.father = father
def myFather(self):
print('my father is ' + self.father)
myHome = Home('jack')
print(myHome.father) # jack
myHome.myFather() # my father is jack
myHome.father = 'Ray'
print(myHome.father) # Ray
del myHome.father
del myHome
但是这边要注意,当删除了之後就无法再被呼叫罗。
最後一种写法是比较特别的状况,通常来讲 class
内容是不能为空的,如果是特殊状况而需要写一个空的 class
是可以使用 pass
语法来避免出错:
class Home:
pass
否则正常来讲你可能会得到「IndentationError: expected an indented block
」这个错误。
那麽这一章节都已经提到 class
,那麽下一章节就闪不掉所谓的继承啦~
最近 Mac 好像在发神经一样,莫名其妙就会准备飞机起飞,难道...它在暗示我该换 M1 了吗 QQ?
<<: 每个人都该学的30个Python技巧|技巧 24:超便利的内建函式—max()、min()、sum()(字幕、衬乐、练习)
>>: TailwindCSS 从零开始 - 让 Variants 成为伪类的强大神器
APCS 分为两个大部分,观念题和实作题。观念题以选择题为主,旨在测试考生对於程序语言的观念是否正确...
简单来说~费氏数列从0 and 1开始~ 後面的每一个数~ 都是前两数相加得来~ 例如,0,1,1,...
iOS APP iOS Test-Driven Development by Tutorials f...
经过了一晚的思考,我认为昨天讲的还不够清楚,因此今天我找了三题相关题目,今天来为大家做更深入的讲解,...
JS 在将值赋予到变数上时 会有两个特性(Call by value(传值) 与 Call by r...