面向对象编程2

 

本节内容:
面向对象高级语法部分 经典类vs新式类  

  • 静态方法、类方法、属性方法
  • 类的特殊方法
  • 反射

Socket开发基础


作业:开发一个支持多用户在线的FTP程序

*************************************

一、类和对象

数据隐藏,即在编写代码过程中尽可能隐藏实现细节。适用于规模大、复杂度高的项目,整个程序的关联性和依赖性很大。一个程序的代码做小小的改动可能连带着整个项目开发都因此必须做出较大的调整,解决这些困难的一个重要方法就是

对象是数据以及数据操作的方法的封装。

1、内建类:由Python预定义的类,例如:str、int、float、list、tuple、dic、set等数据类型。

2、自定义类

格式:

class ClassName:
    indented list of methods for the class

类方法的定义和函数的定义类似,主要区别为类方法的第一个参数为self。当创建一个对象时,每个方法中的self参数都指引这个对象,以便该方法指导具体操作的是哪个对象。

3、类定义实例-矩形类

__init__也叫构造方法,在创建一个对象时被自动调用。为矩阵对象创建_width和_height两个实例变量,实例变量也称作属性

自定义方法不要以双下划线开始和结束。

赋值方法:用于给实例变量赋新值

取值方法:用于获取实例变量的值

其他方法:操作对象实现相应的功能

类对象:objectName=ClassName(arg1,agr2,...)

没有方法的类也是合法的

#保存为文件rectangle.py
class Rectangle:
    # 构造方法
    def __init__(self,width=1,height=1):
        self._width=width
        self._height=height

    #赋值方法
    def setWidth(self,width):
        self._width=width
    def setHeight(self,height):
        self._height=height

    #取值方法
    def getWidth(self):
        return self._width
    def getHeight(self):
        return self._height

    #其他方法
    def area(self):
        return self._width * self._height
    def perimeter(self):
        return 2 * (self._width + self._height)

    #状态表示方法
    def __str__(self):
        return("Width: "+ str(self._width) + "\nHeight: " + str(self._height))

调用上面的矩形类1: 

import rectangle
r=rectangle.Rectangle()
print(r)
print()

r=rectangle.Rectangle()
print(r)
print()

r=rectangle.Rectangle(4)
print(r)

E:\PycharmProjects\PythonStudy\venv\Scripts\python.exe E:/PycharmProjects/PythonStudy/test.py
Width: 4
Height: 5

Width: 1
Height: 1

Width: 4
Height: 1

调用上面的矩形类2: 

import rectangle
r=rectangle.Rectangle()
r.setWidth(4)
r.setHeight(5)
print("The rectangle has the following measurements:")
print("Width is",r.getWidth())
print("Height is",r.getHeight())
print("Area is",r.area())
print("Perimeter is",r.perimeter())

E:\PycharmProjects\PythonStudy\venv\Scripts\python.exe E:/PycharmProjects/PythonStudy/test2.py
The rectangle has the following measurements:
Width is 4
Height is 5
Area is 20
Perimeter is 18

4、类定义实例-纸牌类

#纸牌类
import random
def main():
    c=Card()
    c.selectAtRandom()
    print(c)
class Card:
    def __int__(self,rank="",suit=""):
        self._rank=rank
        self._suit=suit
    def selectAtRandom(self):
        ranks=['2','3','4','5','6','7','8','9','10',
               "jack","queen","king","ace"]
        self._rank=random.choice(ranks)
        self._suit=random.choice(["spades","hearts","clubs","diamonds"])
    def __str__(self):
        return (self._rank+" of "+self._suit)
main()

 

5、学期成绩类 

#保存为文件lgStudent.py
#
学期成绩类 def main(): name=input("Enter student's name:") midterm=float(input("Enter student's grade on midterm exam:")) final=float(input("Enter student's grade on final exam:")) st = LGstudent(name, midterm, final) print("\nNAME\tGRADE") print(st) class LGstudent: def __init__(self,name="",midterm=0,final=0): self._name=name self._midterm=midterm self._final=final def setName(self,name): self._name=name def setMidterm(self,midterm): self._midterm=midterm def setFinal(self,final): self._final=final def calcSemGrade(self): average=(self._midterm+self._final)/2 average=round(average) if average>=90: return "A" elif average>=80: return "B" elif average>=70: return "C" elif average>=60: return "D" else: return "F" def __str__(self): return self._name+"\t"+self.calcSemGrade() main()

E:\PycharmProjects\PythonStudy\venv\Scripts\python.exe E:/PycharmProjects/PythonStudy/test.py
Enter student's name:dream
Enter student's grade on midterm exam:89
Enter student's grade on final exam:90


NAME GRADE
dream A

Process finished with exit code 0

对象列表:列表中的项可以是任一数据类型(包括用户自定义的类):

import lgStudent
def main():
    listOfStudent=[]
    carryOn='Y'
    while carryOn=='Y':
        st = lgStudent.LGstudent()
        name=input("Enter student's name:")
        midterm=float(input("Enter student's grade on midterm exam:"))
        final=float(input("Enter student's grade on final exam:"))
        st=lgStudent.LGstudent(name,midterm,final)
        listOfStudent.append(st)
        carryOn=input("Do you want to continue(Y/N)?")
        carryOn=carryOn.upper()
    print("\nNAME\tGRADE")
    for pupil in listOfStudent:
        print(pupil)
main()

E:\PycharmProjects\PythonStudy\venv\Scripts\python.exe E:/PycharmProjects/PythonStudy/test.py
Enter student's name:dream
Enter student's grade on midterm exam:89
Enter student's grade on final exam:90


NAME GRADE
dream A
Enter student's name:job
Enter student's grade on midterm exam:67
Enter student's grade on final exam:81
Do you want to continue(Y/N)?n


NAME GRADE
job C


Process finished with exit code 0

 

6、初始化方法的其他形式

def __init__(self):
    self._width=1
    self._height=1
def __init__(self,width):
    self._width=width
    self._height=1
def __init(self,width,heigth):
    self._width=width
    self._height=heigth

  

二、继承

 继承是面向对象程序设计的特色,允许基于现有的类来更新创建一个新类(也称子类、派生类)。子类可以继承父类的属性和方法,也可以增加新的自己的属性和方法,同时覆盖父类的方法。

学生成绩类-创建两个子类:

class Student:
    def __init__(self, name="", midterm=0, final=0):
        self._name = name
        self._midterm = midterm
        self._final = final
    def setName(self, name):
        self._name = name
    def setMidterm(self, midterm):
        self._midterm = midterm
    def setFinal(self, final):
        self._final = final
    def __str__(self):
        return self._name + "\t" + self.calcSemGrade()

class LGstudent(Student):
    def calcSemGrade(self):
        average=round((self._midterm+self._final)/2)
        if average>=90:
            return "A"
        elif average>=80:
            return  "B"
        elif average>=70:
            return "C"
        elif average>=60:
            return "D"
        else:
            return "F"
class PFstudent(Student):
    def calcSemGrade(self):
        average=round((self._midterm + self._final)/2)
        if average>60:
            return "Pass"
        else:
            return "Fail"

 

学生成绩类-调用(实现):

import student
def main():
    listOfStudents=obtainListOfStudent()
    displayResults(listOfStudents)
def obtainListOfStudent():
    listOfStudents=[]
    carryOn='Y'
    while carryOn=='Y':
        name=input("Enter student's name:")
        midterm=float(input("Enter student's grade on midterm exam:"))
        final = float(input("Enter student's grade on final exam:"))
        category=input("Enter category (LG or PF)")
        if category.upper()=="LG":
            st=student.LGstudent(name,midterm,final)
        else:
            st=student.PFstudent(name,midterm,final)
        listOfStudents.append(st)
        carryOn=input("Do you want to continue (Y/N)?")
        carryOn=carryOn.upper()
    return listOfStudents
def displayResults(listOfStudents):
    print("\nNAME\tGRADE")
    # listOfStudents.sort(key=lambda x:x.getName())
    for pupil in listOfStudents:
        print(pupil)
main()

E:\PycharmProjects\PythonStudy\venv\Scripts\python.exe E:/PycharmProjects/PythonStudy/test.py
Enter student's name:dream
Enter student's grade on midterm exam:90
Enter student's grade on final exam:98
Enter category (LG or PF)PF
Do you want to continue (Y/N)?N


NAME GRADE
dream Pass

 

三、is-a关系

子类和父类之间构成了is-a关系。例如,每一个LGstudent对象是一个Student地偶像,每一个PFstudent对象也是一个Student对象。

 

四、isinstance函数

用于判断一个对象是否是某个类的对象或其子类的对象

语法如下:isinstance(object,className)

isinstance("hello",str)<==>True

isinstance(3.4,int)<==>False

    if isinstance(pupil,student.LGstudent):
        numberOfLGstudent+=1

五、向子类中添加新的实例变量

 子类只是在其所继承的父类中添加函数。然而,子类也可以在其所继承的父类中增加属性,换句话说,增加实例变量。在这种情况下,子类必须先包含刻画父类属性的初始化方法,然后增加子类的新属性。初始化方法得参数列表顺序是self,父类参数列表和添加子类新参数。

具体第一条语句如下:

super().__init__(parentParameter1,...,patentParameterN)

这条语句后面再接子类新参数的标准声明语句。

 

六、覆盖方法

 子类可以改变它所继承与父类方法得具体操作。如果子类中定义的方法与父类中定义的方法重名,则子类的方法重载父类的方法。

 

七、多态

在不同类中定义具有相同名字方法(但代码实现功能不同),的情况成为多态(polymorphsim),即一种接口多种实现。 

 

posted @ 2018-09-18 23:53  航松先生  阅读(132)  评论(0)    收藏  举报