基础知识回顾——类和对象

面向对象编程是一种编程方式,最主要的特点是需要使用 "类"和 "对象" 来实现,类可以看作一个模板,模板里可以包含很多方法,方法可以实现一些功能;对象则是创建模板的实例,通过实例对象可以执行类中的方法。

1.认识类

通常我们把“鸟类”想象成所有鸟的集合,因此“鸟类”就是一个非常抽象的类;鸟普遍能飞需要食物,因此“能飞”和“需要食物”就是这个类的属性。再者我们不会说这是一只鸟类,而只会说这是一只鸟,于是“这只鸟”便成了“鸟类”的实例。

 1 >>> class Bird:
 2       def __init__(self):
 3           self.hungry = True
 4       def eat(self):
 5           if self.hungry:
 6               print "55555"
 7               self.hungry = False
 8           else:
 9               print "no,thanks!"
10
11 >>> b = Bird()   #b是类Bird的实例
12 >>> b.eat()
13 55555

如果说“鸟类”是一个类,那“百灵鸟”便是“鸟类”的一个子类;反言之,“鸟类”是“百灵鸟”的父类,这是一只百灵鸟,也可以说“这只百灵鸟”是“百灵鸟”的实例化。

 1 >>> class Lark(Bird):
 2       def __init__(self):
 3           self.sound = ‘JOJO‘
 4       def sing(self):
 5           print self.sound
 6
 7 >>> lark = Lark()
 8 >>> lark.sing
 9 <bound method Lark.sing of <__main__.Lark instance at 0x03AB98A0>>
10 >>> lark.sing()
11 JOJO

2.定义子类

通常一个类的定义取决于它所支持的方法,子类可以继承父类所有的方法;于是定义一个子类,便是一个定义更多方法(也可能是重载已经存在的方法)的过程。比如,企鹅Penguin(Bird的子类)不会fly,当创建Penguin类时,可能会想要重写父类的fly方法,对于Penguin的实例来说,这个fly方法要不什么也做不了,要不就会异常,因为企鹅不会飞。

1 >>> lark.eat()   #子类对象调用父类eat()方法
2
3 Traceback (most recent call last):
4      File "<pyshell#61>", line 1, in <module>
5      lark.eat()
6      File "<pyshell#48>", line 5, in eat
7      if self.hungry:
8 AttributeError: Lark instance has no attribute ‘hungry‘

调用Bird类的eat方法异常,是因为Lark类的构造方法__init__被重写了,新的构造方法没有初始化父类hungry属性的代码,正确的应该是在self.sound = ‘JOJO‘代码前,加上Bird.__init__(self),python3.5也可以用super(Lark.self).__init__()代替。

1 >>> class Lark(Bird):
2       def __init__(self):
3           Bird.__init__(self)  #或者super(Lark.self).__init__()
4           self.sound = ‘JOJO‘
5       def sing(self):
6           print self.sound
7
8 >>> lark = Lark()9 >>> lark.eat()  55555

构造方法:代表着名为init的初始化方法,和其他普通方法不同在于,当一个对象被创建后,会立即调用构造方法,用来初始化新创建对象的状态,大多数子类不仅要用于自己的初始化代码,还要父类的初始化代码。

3. 私有方法

方法或特性若公有变为私有(从类外部无法访问),只需要在它的名字前面加上双下划线即可。

 1 >>> class Secretive:
 2       def __A(self):
 3           print ‘no see‘
 4       def B(self):
 5           print ‘hello,you can see me‘
 6
 7 >>> s1 = Secretive()
 8 >>> s1.A()
 9
10 Traceback (most recent call last):
11   File "<pyshell#69>", line 1, in <module>
12     s1.A()
13 AttributeError: Secretive instance has no attribute ‘A‘
14 >>> s1.B()
15 hello,you can see me

4.创建内建类型的子类

一般内建对象是基于类型(list,tuple,string,dic和number)的,自定义的对象则是基于类的。可以创建类但是不能创建类型。但是最新的python,基本类型和类的界限开始模糊了。

 1 >>> class CountList(List):      #定义一个带访问计数的列表
 2       def __init__(self,*args):
 3           super(CountList,self).__init__(*args)    #python2.7不可以用super直接调用自身,获得父类方法,只能用List__init__(self):代替
 4           self.counter = 0
 5       def __getitem__(self,index):
 6           self.count += 1
 7           return super(CountList,self).__getitem__(index)
 8
 9
10 >>> c1 = CounterList(range(5))
11 [1,2,3,4,5]
12 >>> c1.counter
13 0
14 >>>c1[2] +c1[3]
15 7
16 >>>c1.counter
17 2

对象

在Python中一切皆对象,对象(object)基本上可以看作数据(属性)以及操作这些数据的方法组成的集合。对象的特点:

a.多态:意味着可以对不同类的对象使用相同的操作,很多函数和运算符都是多态的

1 >>> def add(x,y):
2       return x + y
3
4 >>> add(1,2)
5 3
6 >>> add(‘abc‘,‘ef‘)
7 ‘abcef‘

b.封装:把类所需要的数据(类的属性)和对数据的操作(类的方法)全部都写进类的过程,简化编程,对外部隐藏内部工作细节。

 1 >>> class Person:
 2       def __init__(self):
 3           self.name = ‘ann‘
 4 >>> p1 = Person()
 5 >>> p1.name
 6 ‘ann‘
 7 >>> p1.name = ‘Ryana‘
 8 >>> p1.name
 9 ‘Ryana‘
10
11 >>> p2 = Person()
12 >>> p2.name
13 ‘ann‘
14 #创建不同的对象p1和p2,名字不同说明对象都有自己的状态,对象的状态由它的属性(eg:name)来描述,对象的方法可以改变它的属性

c.继承:继承是两个类或者多个类之间的父子关系,实现了代码的重用,通过父类为基础建立专门的类对象,以达到调用更多方法的目的。检查继承,issubclass(A,B):A类是否是B类的子类,isinstance(a,A):对象a是否是类A的实例

1 >>> issubclass(Lark,Bird)
2 True
3 >>> issubclass(Bird,Lark)
4 False
5
6 >>> isinstance(lark,Lark)
7 True
8 >>> isinstance(lark,Bird)
9 True
时间: 2024-10-20 09:22:36

基础知识回顾——类和对象的相关文章

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java基础知识回顾之javaIO类--管道流PipedOutputStream和PipedIutputStream

管道流(线程通信流):管道流的主要作用是可以进行两个线程间的通讯,分为管道输出流(PipedOutputStream).管道输入流(PipedInputStream),如果想要进行管道输出,则必须要把输出流连在输入流之上.如图所示: 1.管道输入流应该连接到管道输出流 ,输入流和输出流可以直接连接       2.使用多线程操作,结合线程进行操作.通常由某个线程从管道输入流中(PipedInputStream)对象读取.          并由其他线程将其写入到相应的端到输出流中.不能使用单线程

java基础知识回顾之---java String final类之intern方法

public class StringObjectDemo { /** * @param args */ public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " ");//true System.out.print((Other.hello == hel

java基础知识回顾之javaIO类--RandomAccessFile类

java.io 类 RandomAccessFile java.lang.Object java.io.RandomAccessFile1.该类不是IO流中的子类.2.该类既能读又能写.3.该对象内部分装了一个字节数组,通过指针可以操作数组中的元素.4.其实该对象就是将字节输入流和输出流进行了封装.5.该对象只能对文件操作,目的和源只能是文件对象.通过看构造方法可以看得出来.RandomAccessFile(File file, String mode) RandomAccessFile(Str

java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析

/** *   栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放  在常量池中). 堆(heap):存放所有new出来的对象. *   静态存储:存放静态成员(static定义的). 常量池(constant pool):在堆中分配出来的一块存储区域,存放储显式的String常量和基本类型常量(float.int等).另外,可以存储不经常改变的东西 *                       p

java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // TODO Auto-generated method stub while(true){ if(ticket > 0){//当线程0被调起的时候,当执行到这条判断语句的时候,线程1被调起抢了CPU资源,线程0进入冻结状态. try { Thread.sleep(100);//中断当前活跃的线程,或者

java基础知识回顾之java Thread类学习(把)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解

看API文档介绍几个方法:  JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock                    2.接口Condition:Condition替代了Object监视器方法(wait.notify.notifyAll),分别替换成了await(),signal() (唤醒一个等待线               程),signalAll() 唤醒多个线程.一个锁可以绑定多个condition对象,可以对应好几组wait,