十六、面向对象编程

面向对象编程类的概念 : 具有相同属性和技能的一类事物人类 抽象对象 : 就是对一个类的具体的描述具体的人 具体

使用面向对象的好处:    使得代码之间的角色关系更加明确    增强了代码的可扩展性    规范了对象的属性和技能面向对象的特点:结局的不确定性
 1 def Person(name,sex,hp,ad):
 2     # 人模子
 3     self = {‘name‘: name, ‘sex‘:sex, ‘hp‘: hp, ‘ad‘: ad}
 4     def attack(dog): # 闭包
 5         # 人攻击狗
 6         print(‘%s攻击%s‘ % (self[‘name‘], dog[‘name‘]))
 7         # 狗掉血,狗的血量-人的攻击力
 8         dog[‘hp‘] -= self[‘ad‘]
 9     self[‘attack‘] = attack
10     return self
11
12 def Dog(name,kind,hp,ad):
13     # 狗模子
14     self = {‘name‘: name, ‘kind‘:kind, ‘hp‘: hp, ‘ad‘: ad}
15     def bite(person):
16         print(‘%s咬了%s‘ % (self[‘name‘], person[‘name‘]))
17         # 人掉血,人的血量-狗的攻击力
18         person[‘hp‘] -= self[‘ad‘]
19         if person[‘hp‘] <= 0: print(‘game over,%s win‘ % self[‘name‘])
20     def bite2():pass
21     self[‘bite‘] = bite
22     self[‘bite2‘] = bite2
23     return self
24
25 # 人 规范了属性的个数 简化了创造任务的代码
26 alex = Person(‘a_sb‘,‘不详‘,1,5)
27 boss_jin =Person(‘金老板‘,‘女‘,2,50)
28
29 # 狗
30 chen = Dog(‘旺财‘,‘teddy‘,50,20)
31 alex[‘attack‘](chen)
32 print(chen[‘hp‘])
在讲语法规则之前我们先说下类的基础的东西静态属性
 class Person:         #类名
     role = ‘person‘   # 静态属性
     def f1(self):     # 动态属性 方法(函数)  默认带一个参数self
         print(1234567)
查看静态变量的第一种方法:
print(Person.__dict__)   把类中的所有的变量以字典的方式打印出来
print(Person.__dict__[‘role‘])    把role对应的值打印出来
查看静态变量的第二种方法:
print(Person.role)
Person.role = 123  改变了静态属性的值
Person.__dict__[‘role‘] = 456   报错
del Persom.sole     删除静态属性 
动态属性和一些语法规则

引用动态变量        # 1.类名.方法名  查看这个方法的内存地址        # 1.类名.方法名(实参)  调用了这个方法,必须传一个实参,这个实参传给了self    # 创造一个对象 - 实例化        # 产生一个实例(对象)的过程        # 对象 = 类名()# alex = Person()   # 创造一个对象# alex 是对象、实例# Person是类# 对象 = 类名()

# 实例化的过程:    # 1.创造一个实例,将会作为一个实际参数  # python    # 2.自动触发一个__init__的方法,并且把实例以参数的形式传递给__init__方法中的self形参    # 3.执行完__init__方法之后,会将self自动返回给alex# __init__方法 :初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值# 对象    # 在类的内部 self是本类的一个对象    # 在类的外部,每一个对象都对应着一个名字,这个对象指向一个对象的内存空间    # 属性的调用:        # 对象名.属性名               第一种调用方法        # 对象名.__dict__[‘属性名‘]   第二种调用方法    # 方法的调用 :        # 类名.方法名(对象名)  # 那么方法中的self参数就指向这个对象        # 对象名.方法名()      # 这样写 相当于  方法中的self参数直接指向这个对象
class Person:
    s = ‘aaaa‘
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad
    def atack(self):
        print(‘%s攻击%s‘ % (self.name,gou.name))
class Dog:
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad
    def bite(self):
        print(‘%s咬了%s‘ % (self.name,alex.name))
print(Person.s)
alex = Person(‘alex‘,‘male‘,78,23)
gou = Dog(‘wangcai‘,‘female‘,4,56)
print(alex.__dict__)
print(alex.name)
alex.name = ‘sb‘
print(alex.name)
alex.atack()
gou.bite()
Person.atack(alex)
Dog.bite(gou)#############

aaaa
{‘name‘: ‘alex‘, ‘sex‘: ‘male‘, ‘hp‘: 78, ‘ad‘: 23}
alex
sb
sb攻击wangcai
wangcai咬了sb
sb攻击wangcai
wangcai咬了sb




 面向对象中的一些作用域问题

在创建一个类时,类里面的静态变量和方法 公用一个内存空间
每个对象里的 所有对象属性公用一个内存空间  内存空间里面包含一个类对象指针 当在自己的空间找不到对象属性时 就通过类对象指针去类的内存空间去找
对类静态属性的更改 应该使用 类名.静态属性 = 新的值
class Person:
    role = ‘person‘   # 静态属性
    def __init__(self,name,sex,hp,ad):  # 方法
        self.name = name     # 对象属性 属性
        self.sex = sex
        self.hp = hp
        self.ad = ad
        self.attack = ‘hahaha‘
    def attack(self):
        print(‘%s发起了一次攻击‘%self.name)

alex = Person(‘a_sb‘,‘不详‘,1,5)
boss_jin = Person(‘金老板‘,‘女‘,50,20)
print(alex.role)
print(boss_jin.role)
alex.role = ‘dog‘             #这句代码是在自己的空间内创建了一个对象属性 role = ‘dog’
print(alex.role)                #这句代码在找role这个对象属性时 先找自己的空间
print(boss_jin.role)    #     结果为‘person‘  这个在自己的空间找不到所以去找了类的空间里的role

 组合 

组合:一个类的对象作为另一个类的对象的属性     表示一种什么有什么的关系

能够组合必须是两个对象有可以互相关联的因素。

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    def s(self):
        return pi*self.r**2
    def lenth(self):
        return 2*pi*self.r
class Ring:
    def __init__(self,r,R):
        self.r = Circle(r)              组合
        self.R = Circle(R)              组合
    def s(self):
        return abs(self.r.s() - self.R.s())
    def lenth(self):
        return self.r.lenth() + self.R.lenth()
a = Ring(3,5)
print(a.s(),a.lenth())

继承

父类 :基类 超类子类 :派生类

继承的特点:什么里面是什么的关系  继承是当几个类的对象都有共同的属性的时候可以用继承这样可以不用输入重复的代码。

      含有继承关系的子类在找东西的时候先找自己内存空间 再找自己类的空间  再找父类空间

 

class Animal:
    role = ‘Animal‘
    def __init__(self,name,hp,ad):
        self.name = name     # 对象属性 属性
        self.hp = hp         #血量
        self.ad = ad         #攻击力

    def eat(self):
        print(‘%s吃药回血了‘%self.name)

class Person(Animal):
    r = ‘Person‘
    def attack(self,dog):   # 派生方法
        print("%s攻击了%s"%(self.name,dog.name))

    def eat2(self):
        print(‘执行了Person类的eat方法‘)
        self.money = 100
        self.money -= 10
        self.hp += 10

class Dog(Animal):
    def bite(self,person):  # 派生方法
        print("%s咬了%s" % (self.name, person.name))
alex = Person(‘alex‘,10,5)
dog = Dog(‘teddy‘,100,20)
alex.eat2()
alex.eat()
dog.eat()
alex.eat = ‘aaa‘
print(alex.eat())  # 报错

###############
执行了Person类的eat方法
alex吃药回血了
teddy吃药回血了

派生

在继承父类属性的时候,假如几个子类的90%的属性都相似,而只有剩下的10%不一样,这时候就需要用到派生属性的方法

class Animal:
    def __init__(self,kind,sex):
        self.kind = kind
        self.sex = sex
    def func1(self):
        return ‘吃‘
    def func2(self):
        print( ‘喝‘)
class Dog(Animal):
    def __init__(self,kind,sex,kg):
        # Animal.__init__(self,kind,sex)
        super().__init__(kind,sex)    在单继承中supper负责找到父类的,不需要传self
        self.height  = kg             派生属性
    def func3(self):
        print(‘看门‘)
    def func1(self):
        print(‘抓老鼠‘)
class Cat(Animal):
    def __init__(self,kind,sex,age):
        Animal.__init__(self,kind,sex)
        self.age = age
    def func4(self):
        print(‘上树‘)
        super().func2()              找父类的中的方法
dog = Dog(‘二哈‘,‘male‘,‘30kg‘)
cat = Cat(‘加菲猫‘,‘female‘,3)
print(dog.__dict__)
print(cat.__dict__)
cat.func4()
########
{‘kind‘: ‘二哈‘, ‘sex‘: ‘male‘, ‘height‘: ‘30kg‘}
{‘kind‘: ‘加菲猫‘, ‘sex‘: ‘female‘, ‘age‘: 3}
上树
喝

砖石继承问题

在python3x 中所有的类都是新式类(所有的类都默认含有object)所以内部的遍历顺序都是以广度优先的顺序来遍历,当用super的时候请看下面的例子

  

class A:
    def func(self):
        print(‘A‘)
class B(A):
    pass
    def func(self):
        super().func()
        print(‘B‘)
class C(A):
    pass
    def func(self):
        super().func()
        print(‘C‘)
class D(B):
    pass
    def func(self):
        super().func()                          
        print(‘D‘)
class E(B,C):
    pass
    def func(self):
        super().func()
        print(‘E‘)
class F(D,E):
    pass
    def func(self):
        super().func()
        print(‘F‘)
f = F()
f.func()print(mro(f))  查找他的上一个父类 这段代码super查找父类中的方法查找顺序就如图所示  遵循广度优先的顺序 并且每次找遍历节点只遍历一次

在python2x 中就不一样了python2中的砖石继承分为经典类和新式类

经典类(也就是不含有object):在经典类中在子类寻找父类的时候遵循深度优先 没有mro方法 也没有super方法

新式类(就是含有object):在新式类中在子类寻找父类的时候遵循广度优先  有mro方法 也有super方法但是super方法要有传参super(子类名称,子类对象)

这个例子为经典类的遍历方法class A:
    # def func(self):
    #     print(‘A‘)
    pass
class B(A):
    pass
    # def func(self):
    #     # super().func()
    #     print(‘B‘)
class C(A):
    pass
    def func(self):
        # super().func()
        print(‘C‘)
class D(B):
    pass
    # def func(self):
    #     # super().func()
    #     print(‘D‘)
class E(B,C):
    pass
    # def func(self):
    #     # super().func()
    #     print(‘E‘)
class F(D,E):
    pass
    # def func(self):
    # #     # super().func()
    # print(‘F‘)
f = F()
f.func()

抽象类和接口类

说这个问题之前我们要先来聊聊编程届的两本黑皮书

《设计模式》 该书中记载了很多衍生下来的很多程序的设计模式    比如JAVA语言的单继承的设计模式,因为在java语言中没有多继承。

《算法导论》 记载了很多经典的算法 及时在今天没有用了的一些算法  都记录了下来

我们继续来说抽象类和接口类  接口类和抽象类都只是一种编程规范  只是为了规范编程而已,并不能让你的程序变得这么样,如果这个程序只由我自己一个人来完成 我自己遵守默认的规范那么我就不需要进行这些操作

来我们看一段代码

这段代码中的class A 就是抽象类  抽象类的目的是为了下面的类都继承A类的方法   因为在调用方法的时候用了一个归一化设计  以免其他的程序员在创建类的方法的时候没有创建抽象类的方法导致归一化设计的函数在调用类的方法的时候出错from abc import ABCMeta,abstractmethod
class A(metaclass = ABCMeta):
    @abstractmethod
    def pay(self):pass
class Alipay(A):
    def pay(self,money):
        print(‘支付宝支付%s元‘ % money)
class QQpay(A):
    def pay(self,money):
        print(‘用qq支付了%s元‘ % money)
class WEchat(A):
    def pay(self,money):
        print(‘用微信支付%s元‘ % money)
a = Alipay()
B = QQpay()
c = WEchat()
def pay(a,money):           这里就是归一化设计
    a.pay(money)
pay(a,100)
pay(B,200)
pay(c,300)
######
支付宝支付100元
用qq支付了200元
用微信支付300元

我们在来看另一个代码

from abc import ABCMeta,abstractmethod
class FlyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):pass
    @abstractmethod
    def cal_flying_speed(self):pass
    @abstractmethod
    def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class SwimAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class Tiger(WalkAnimal,SwimAnimal):
    def walk(self):pass
    def swim(self):pass
class Monkey:
    def walk(self):pass
    def climb(self):pass
class Swan(FlyAnimal,WalkAnimal,SwimAnimal):
    def swim(self):pass
    def walk(self):pass
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass
class Parrot(FlyAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self): pass

 上面这段代码中我们可以看到当多个类中有相同也有不同的方法,一个类中包含几个抽象类中的方法,这时候也由于java没有多继承 所以当java遇到这种情况的时候 就需要将我们python中的抽象类 建成接口类  以便于多继承  也就是说java只可以多继承接口类

总结:无论是抽象类也好 还是接口类都是为了规范代码

    接口类:是java的概念 所以说接口类只存在java中,是方便java中解决多继承的问题的  同时还有接口隔离的问题(因为当不同的类包含有多种不同的方法时候,就需要建立不同的接口类来隔离)      

         抽象类  :在python中就是用来规范代码的   在python中遇到不同的类包含不同的方法 又需要规范每个类中的方法名  这时候我们就需要建立不同的抽象类

 多态 

 在说多态之前我们首先来认识下什么是强类型语言什么是弱类型语言

强类型:c c+ c++  c# java 这些强类型的语言都有个共性就是在传参的时候有个特点 只能传一种数据类型的参数

强弱型语言:python

弱类型的语言:php    shel   这些语言在数据类型上就没有那么严格    

什么是多态我们看下面这个代码

from abc import ABCMeta,abstractmethod
class A(metaclass = ABCMeta):
    @abstractmethod
    def pay(self):pass
class Alipay(A):
    def pay(self,money):
        print(‘支付宝支付%s元‘ % money)
class QQpay(A):
    def pay(self,money):
        print(‘用qq支付了%s元‘ % money)
class WEchat(A):
    def pay(self,money):
        print(‘用微信支付%s元‘ % money)
a = Alipay()           这里我们看下a 的数据类型为<class ‘__main__.Alipay‘>
B = QQpay()                      B 的数据类型为 <class‘__main__.QQpqy‘>
c = WEchat()                     c 的数据类型为<class‘__main__.WEchat‘>
def pay(a,money):
    a.pay(money)
pay(a,100)
pay(B,200)
pay(c,300)
######
支付宝支付100元
用qq支付了200元
用微信支付300元

 上面我们看到了所有的实例化后打变量名的数据类型都为类名  而在我们在调用归一化设计的函数时,传入的第一个位置参数的数据类型时不一样的  在java中是不行的  因为他强语言的特性   所以是绝对不允许每次都传入不同的数据类型 那怎么办呢 ??所以就只有再建立一个父类,让子类都来继承父类,把归一化的函数的传参的数据类型改成父类,传参时 传入子类的数据类型就可以了  ,这也就是java实现多态性的办法。

而这样复杂的问题在python中就不存在了,由于python自带多态性,所以这种问题根本就不存在。

我们深究一下为什么python会自带多态,其实说白了是那些编写python的大佬 达成了一种默契 直接把各种父类子类的问题都解决好了 都写成一样的方法名 所以python才会自带多态

编程原则:

开放封闭原则:对扩展是开放的 对修改是关闭的(比如说装饰器就是对这个原则的执行)

依赖倒置原则:底层依赖上层

接口隔离原则:上面说过了我们据不在叙述了

封装

说道这里咱们再来和java做下对比

public  共有的  在类的内部可以使用  子类可以使用 外部可以使用           python中所有的都可以做到

protect 保护的  在类的内部可以使用  子类可以使用  外部不能使用         Python中没有

private 私有的  在类的内部可以使用  子类不可以使用 外部不能使用     python  中的__名

封装什么叫封装,就是我要把有些属性,和方法,对象的属性封装起来,不愿意在类的外面直接调用修改。     

我们来看一个面试题

class D:
    def __init__(self):
        self.__func()
    def __func(self):
        print(‘in D‘)

class E(D):
    def __func(self):
        print(‘in E‘)
e = E()###in D分析:第一步实例化 然后自动执行了D类中的def__init__(self):  self.__func()  找到D类中的私有的方法__func()父类不想让子类继承自己方法也可以让方法私有化,这样就不能再外面调用父类的方法如果要调用E中的__func()则要这样写e._E__func() 但是这样虽说可以调用 但是我们绝不可以这样写 这样只是可以做到。


 @property 关键字我们在写类的方法的时候经常会遇到一些方法是动作但是我们得到的结果只是个名词,我们为了规范代码会使用property这个关键字,也就是把方法伪装成属性。但是需要注意的是,使用property时,这个方法的的参数只能有一个参数(self)@类名.setter这种方法是用来对伪装的属性进行赋值时候调用的方法    需要注意的是方法名必须和要伪装的方法名一致  并且赋值的时候调用的方法名也要一致
class A:
    def __init__(self,name,discount,price):
        self.name = name
        self.__discount = discount
        self.__price =price
    @property
    def dis_price(self):                            一致dis_price
        return self.__discount*self.__price
    @dis_price.setter                               一致dis_price
    def dis_price(self,newdiscount):
        self.__discount = newdiscount
apple = A(‘apple‘,0.8,5)
print(apple.dis_price)
apple.dis_price = 0.3                               一致dis_price
print(apple.dis_price)
####
4
1.5这里需要注意的是 如果在类中再建立一个和伪装方法名一个属性,则会被将内伪装的方法名覆盖,打印出来的是方法的内存地址
 @方法名.deleter  删除方法 这个基本上不用   删除属性
class Person:
    def __init__(self,n):
        self.__name = n  # 私有的属性了
    @property            # 重要程度 ****
    def name(self):
        return self.__name
    @name.deleter
    def name(self):
        print(‘name 被删除了‘)
    @name.deleter         # 重要程度*
    def name(self):
        del self.__name

p = Person(‘alex‘)
print(p.name)
del p.name  # 只是执行了被@name.deleter装饰的函数
print(p.name)

@classmethod这个我们举两个例子看下面的代码
class A:
    discount__ = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def really_price(self):
        return self.__price*A.__discount
    @classmethod                                 类方法:可以直接被类调用 不用再实例化  并且只需要传一个类参数 当
    def new_discount(cls,newdiscount):
        cls.__discount = newdiscount
A.new_discount(0.8)                                        只需要传一个参数
a = A(‘a‘,3)
print(a.really_price)由这段代码可以看出 当折扣恢复到原来的状态时只需要进行如下操作A.new_discount(1)所以当一个方法需要使用类中的静态属性时 而不需要其他操作时 就用类方法
@staticmethod
class Student:
    def __init__(self,name):pass
    @staticmethod
    def login():                   # login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可
        user = input(‘user :‘)
        if user == ‘alex‘:
            print(‘success‘)
        else:
            print(‘faild‘)
Student.login()

当一个方法既不需要用到对象中的属性又不需要用到类中的静态属性  就可以用到静态方法来直接调用类中的方法 不需要实例化
 
 

原文地址:https://www.cnblogs.com/yyyyyyyyyy/p/8781981.html

时间: 2024-08-02 01:12:26

十六、面向对象编程的相关文章

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: ? ? ? ? ? ?将一些东西封装到一个地方,你还可以取出来 ? ? ? ? ? ?类设置静态属性, 设置一些方法 或者 对象, 对象可以在其对象封装一些属性 多态: ? ? ? ? ? ?python默认支持多态, 多态指的是一种事务具有多种形态 ? ? ? ? ? ?1.多态可以增加代码的灵活度: ? ? ? ? ? ?2.以继承和重写父类方法为前提: ?

Java编程思想学习(十六) 并发编程

线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础. 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是真正的并行运行,而是通过时间片切换来执行,由于时间片切换频繁,使用者感觉程序是在并行运行.单核心CPU中通过时间片切换执行多线程任务时,虽然需要保存线程上下文,但是由于不会被阻塞的线程所阻塞,因此相比单任务还是大大提高了程序运行效率. 1.线程的状态和切换: 线程的7种状态及其切换图如下: 2.多线

十六. 面向对象上下文管理协议

一. __enter__和__exit__ 我们知道在操作文件对象的时候可以这么写 1 with open('a.txt') as f: 2 '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 # 上下文管理协议 class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__

python学习笔记(六) - 面向对象编程

一. 类和实例 aa 二. 访问限制 bb 三. 继承和多态 cc 四. 获取对象信息 dd

Go语言学习(十二)面向对象编程-结构体

1.结构体的初始化方式 例如自定义一个结构体 package main import( "fmt" ) type Rect struct{ //type和struct为关键字 x,y float64 //结构体成员 widh,height float64 } func (r *Rect) Area() float64{ return r.width * r.height } func main(){ //初始结构体的几种方式: rect1 := new(Rect) rect2 := &

面向对象设计与面向对象编程

我发现,面向对象设计,被忽视的太严重了.使用OOP语言,却不是面向对象来设计.无非就是用类写C程序而已,而且这种情况还很常见.另一种情况是过度重视类,而忽视了对象,但是对象才是根本.不过本文会以类型为主,来介绍面向对象设计. 前言 面向对象是一个完全不同于传统软件设计方式的理念,传统软件设计是以功能为主体,以功能为模块,以功能为目标.而面向对象不同,是以软件运行中的组件为主体,实现某个功能,只是恰好这些组件的交互可以间接做到.这些组件,就是对象.用面向对象来设计软件,实际上就是设计一系列的对象,

面向对象程序设计-C++ Finial exam review NOTES【第十六次上课笔记】

写在前面: 我记得也不全,如果有记录的更全的同学可以留言,我会添加哒 :) 常量 内敛函数 为什么需要内敛函数 内敛函数适用于什么场合 内敛函数本身,最大优点是,避免了真正函数调用的开销 因为普通函数调用会有开销,比如开辟一个栈,结束了还要释放局部变量 如果函数体只有寥寥几行,是不值得使用函数 在函数体代码比较短小的时候,使用频繁的,应该使用内敛函数 最大优点:没有函数调用开销,又解决了带有参数宏的简单替换,它有类型检查 引用 什么是引用:给这块区域的数据再增加一个名称(本质含义) 表面上看,相

大数据笔记(二十四)——Scala面向对象编程实例

===================== Scala语言的面向对象编程 ======================== 一.面向对象的基本概念:把数据和操作数据的方法放到一起,作为一个整体(类 class) 面向对象的特征: (1)封装 (2)继承 (3)多态 二.定义类: class,没有类的修饰符: public.protected.private class Student1 { //定义属性 private var stuName:String = "Tom" privat

张季跃 201771010139《面向对象程序设计(java)》第十六周学习总结

张季跃 201771010139<面向对象程序设计(java)>第十六周学习总结 1.实验目的与要求 (1) 掌握线程概念: (2) 掌握线程创建的两种技术: (3) 理解和掌握线程的优先级属性及调度方法: (4) 掌握线程同步的概念及实现技术: 2.实验内容和步骤 实验1:测试程序并进行代码注释. 测试程序1: l 在elipse IDE中调试运行ThreadTest,结合程序运行结果理解程序: l 掌握线程概念: l 掌握用Thread的扩展类实现线程的方法: l 利用Runnable接口