python高级 - 面向对象

有关面向对象的定义,我不在阐述,在我之前的Java基础文章中已经阐述的相对很清除了,这里我们直接来进行学习以及操作。
这里我将脱离网站上的教学,直接与Java对比学习,我相信对于任何一个掌握了另外一门语言的人来说,对比学习,应该是最快上手的。

创建一个类
python:

class Dog:
    #名字
    name =""
    #颜色 双下划线+属性名 这个属性就会变成伪私有
    __color=""

    #构造器   参数:类型 (当然,:和类型你可以不写,
    # 但是作为曾经写强类型语言的开发人员,不写类型实在有点难受...)
    #self 就相当于 Java中的自动传入的this引用
    def __init__(self, name:str, color:str):
        self.name = name
        self.__color = color

    def _toString(self):
        print("Dog:  name='{}', color='{}' ".format(self.name,self.__color))

#new这个关键字在Python中并不存在,直接使用 类名()就是在创建对象
dog = Dog("大黄","yellow")
dog._toString()

#改变共有属性
dog.name = "蠢蠢"
#改变私有属性
# dog.__color("red")  因为这是私有属性,如果没有set方法,我们不能从外部修改它
#然后说这个是伪私有是有原因的,实例._类型__私有属性 照样可以修改和访问
dog._Dog__color = "red"
dog._toString()

# 结果:Dog:  name='大黄', color='yellow' 
#      Dog:  name='蠢蠢', color='red' 

java:

public class Dog {
    //名字
    public String name;
    //颜色
    private String color;
    //构造器
    Dog(String name , String color){
        this.name = name;
        this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                '}';
    }

    public static void main(String args[]){
        Dog dog = new Dog("大黄","yellow");
        //改变共有属性
        dog.name = "蠢蠢";
        System.out.println(dog);
        //改变私有属性
        dog.setColor("red");
        System.out.println(dog);
    }

}

//结果:Dog{name='蠢蠢', color='yellow'}
//     Dog{name='蠢蠢', color='red'}

简单总结一下,创建类:

class <类名>:
	#构造器,注意一个类只能由一个构造器,在Python中方法是可以给默认参数的,
	#所以不需要多余的构造器进行重载
	def __init__(self,参数1,参数2):
		#代表什么都不做
		pass

对象

创建一个对象

# 构造器 __init__ 中的self 代表着当前这个对象,会自动传入,所以只要传入需要的参数即可
对象名 = 类名(参数1,参数2) 

创建一个对象时,会自动调用构造器,也就是 __init__(self)方法

销毁一个对象时,对自动调用析构函数,__del__(self),类似Java中的 finallize。简单来说是将对象回收的方法,一般不会进行显示调用,并且也不会重写它。

访问权限

python中可以说不存在访问权限,所有属性,所有的方法都是共有的,而在OOP中,访问权限还是要有的,所有Python中有了伪私有

#共有属性
name = "zhangsan"
#私有属性  外部还是可以通过 实例名._类名__属性或方法 进行访问
__sex = "男"
public String name = "zhangsan"
private String sex = "男"

属性和方法调用

class A:
	 name = "张三"
	 def __init__(self):
		#代表什么也不做
	 	pass
	 #注意,对象方法都要有一个基本参数就是self,
	 def getName(self):
	 	return self.name
a = A()
#调用方法
a.getName()

为什么必须要传入self?简单来说就是要确定是那个对象调用的这个方法。(至少在IDE环境中都要求必须传入一个self)这就是一个实例方法,也叫对象方法

类方法:需要用**@classmethod**修饰

class C:
	name = "zs"
	@classmethod
	#必须要传一个参数代表当前类,普遍将第一个参数定义为cls,定义为其他名字也无所谓
	def  fun(cls):
		print(cls.name)
		
	def fun2(self):
		print(self.name)
	#也可以将普通方法转为类方法
	fun2 = classmethod(fun2)
	
c = C()
c.name ="ls"
#对象也能够调用类方法
#注意哪怕对象调用了类方法,类方法的内容是对类的某一个属性进行改变
#与对象的属性无关
c.fun1()
c.fun2()
print(c.name)
# ls
print(C.name)
# zs

静态方法,需要用 @staticmethod 修饰
静态方法与Java不同,Java的静态方法实际上就是类方法,但是Python将它分开处理了
对象和类都可以调用静态方法,并且不会自动传入任何值。

class StaicTest:
	str = "static method Test"
	
	@staticmethod
	def test():
		print(StaticTest.str)
	
	@staticmethod
	def test2(a,b):
		print(a,b)

	def test3(self):
		print("它被转为了静态方法")
		
	#如果这样做,会直接报错
	#所以对象方法和类方法,不能强转为静态方法
	test4 = staticmethod(test3)
	
st = StaticTest()
st.test()
#static method Test
st.test2("a","b")
#a b

继承

Python的每一个类都继承自Object 类,这点与Java 很相像。
他会继承父类所有的非私有方法以及非私有属性。
(注意! 子类的属性或者方法与父类有重名的现象,直接进行覆盖)

class 类名(父类名):
	pass

如果一旦有重名的方法,那么子类的方法会覆盖父类的方法。

class father(object):
    name = "123"
    def __init__(self):
        self.name = "fatherName"
        print("father类初始化")
	def __privateFun__(self):
		print("父类的私有方法无法继承")
	
    def fatherMethod(self):
        print("father的普通方法")

    @classmethod
    def fatherClassMethod(cls):
        print("father的类方法")

    @staticmethod
    def fatherStaticMethod():
        print("father的静态方法")
        
class son(father):
    pass

s = son()
print(s.name)
#结果: fatherName

class son1(father):

    def __init__(self):
        print("son1初始化")

s1 = son1()
print("访问", "不到父类的name,因为重写了__init__方法导致无法初始化父类"
            if s1.name=="" else s1.name)
#结果: son1初始化
#     访问 不到父类的name,因为重写了__init__方法导致无法初始化父类

所以说,当我们的子类继承父类时,如果子类重写了构造方法,也就是自定义了__init__ () 方法,那么就不会默认调用父类的构造器,所以会造成父类的对象,在子类中无法被调用的情况。

如果说子类要自己进行初始化,并且也要将对应的父类进行初始化,那么就可以直接使用super关键字来调用,或者使用 父类.__init__方法进行传值,

class son1(father):

    def __init__(self):
        #初始化父类
        super(son1,self).__init__()
        #又或者
        #super().init(参数1,参数2,参数3....)
        #使用父类的构造器方法
        # father.__init__(self)
        print("son1初始化")

总结,显示调用父类的构造器的方法方式有两种:
super(子类,self).__init__(参数1,参数2....) 或 super().__init__(参数1,参数2,参数3)
父类.__init__(子类的self,参数1,参数2....)

在Pyhon中,并不是一种单继承的模式。
一个类可以有好几个父类,也就是多重继承,但是我建议,除非必要并且确定,否则不要使用多重继承。

class Base1:
    def fun1(self):
        print("Base1 的方法")

class Base2:
    def fun2(self):
        print("Base2 的方法")

class SuperClass(Base1,Base2):
    pass

s = SuperClass()
s.fun1()
s.fun2()

抽象类

抽象类:具有抽象方法的类就是抽象类。也就是说作为一个抽象类,只定义好要做什么事情,具体怎么干,要子类自己具体实现。
定义抽象方法,需要用到 模块 以及 @abc.abstractmethod,所以我们需要导入模块 abc。

import abc
class pay(object):
	#不需要实现,让子类进行实现。
    @abc.abstractmethod
    def pay(self):
        pass


class AliPay(pay):

    def pay(self):
        print("支付宝支付")

class WxPay(pay):

    def pay(self):
       print("微信支付")

ap = AliPay()
wp = WxPay()
ap.pay()
wp.pay()

#结果:支付宝支付
#微信支付

并且有一系列的抽象设计,但实际上常用的还是就这个 @abc.abstractmethod
在这里插入图片描述

接口

python中并没有接口类型,实际上接口本质上就是抽象类。所以在Python中接口成为了一种描述,而不是定义。真正使用的还是抽象类。我们可以发现哪怕是在Java中,接口的功能也越发的趋向抽象类,所以python这么做,也是大势所趋,并且简单好用。

多态

多态的关键有三个,继承,重写,向上转型
在python中很难做到向上转型(主要是我没有查出来…)

import abc
class Animal(object):

    def __init__(self):
        pass
	#定义一个抽象方法,注意抽象方法也是可以写方法体的。
    @abc.abstractmethod
    def eat(self):
        pass

class Dog(Animal):

    def eat(self):
        print("小狗在吃骨头")

class Cat(Animal):
    def eat(self):
        print("小猫在吃鱼")

#多态实现函数放到了程序的主函数中
def eat(self):
    self.eat()

d = Dog()
c = Cat()
#d = Animal(d) 这个的意思是调用了Animal的__init__函数,传入了d这个对象
#直接报错,因为我们并没有定义一个__init__(self,参数)的方法。

eat(d)
#小狗在吃骨头
eat(c)
#小猫在吃鱼

导入包

其实到现在没有解决一个问题,就是我们自己写的一个py文件,怎么样让其他的py文件进行访问呢???
在这里插入图片描述

在这里插入图片描述
这里我们在OOP2中使用OOP1中的类,我们发现只要按需导入即可。从 from 这个目录下,HightStudy ,导入import BaseOOP1 这个模块。
非常容易理解。也很类似Java

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值