Python利用抽象方法实现类似Golang的interface

说到goalng的interface,在学习了golang的interface的使用后一度感觉它有点像(没有说完全一样)python利用abstractmethod实现的对象的多态性

1.我们再来看下python利用abstractmethod实现对象的多态性

什么是多态性即一个接口,多种实现

import abc
import math


class Shape(metaclass=abc.ABCMeta):  # 该类类似go中的interface,继承该类的子类必须实现其抽象方法,不然运行时会报错
  @abc.abstractmethod
  def perimeter(self):
    pass

  @abc.abstractmethod
  def area(self):
    pass

  def name(self):  # 子类不实现非abstractmethod不会有影响
    pass


class Rectangle(Shape):
  def __init__(self, length, width):
    self.length = length
    self.width = width

  def perimeter(self):
    return (self.length + self.width) * 2

  def area(self):
    return self.length * self.width


class Triangle(Shape):
  def __init__(self, sideA, sideB, sideC):
    self.sideA = sideA
    self.sideB = sideB
    self.sideC = sideC

  def perimeter(self):
    return self.sideA + self.sideB + self.sideC

  def area(self):  # 如果不实现父类的该抽象方法同样会报错在运行时
    p = self.perimeter() / 2
    return math.sqrt(p * (p - self.sideA) * (p - self.sideB) * (p - self.sideC))


r = Rectangle(4, 5)
t = Triangle(6, 7, 8)


def func(obj):
  print(obj.area(), obj.perimeter())


func(r)
func(t)

2.首先我们简单回忆一下golang的interface的使用

任何自定义的类型要实现Shape接口都很简单,只需要实现Shape内部所有的方法签名即可。和其他需要显式声明接口实现类的语言不同,在Go语言中,接口的实现是隐式的。即我们不用明确地指出某一个类型实现了某一个接口,只要在某一类型的方法中实现了接口中的全部方法签名,就意味着此类型实现了这一接口。

package main

import (
	"fmt"
	"math"
)

type Shape interface {
	perimeter() float64
	area() float64
}
type Rectangle struct {
	length float64
	width  float64
}

func (r Rectangle) perimeter() float64 {
	return (r.length + r.width) * 2
}
func (r Rectangle) area() float64 {
	return r.length * r.width
}

type Triangle struct {
	sideA, sideB, sideC float64
}

func (t Triangle) perimeter() float64 {
	return t.sideA + t.sideB + t.sideC
}
func (t Triangle) area() float64 {
	p := t.perimeter() / 2
	return math.Sqrt(p * (p - t.sideA) * (p - t.sideB) * (p - t.sideC))
}
func main() {
	var s Shape
	s = Rectangle{
		length: 12,
		width:  8,
	}
	fmt.Println("Rectangle perimeter is ", s.perimeter(), ",area is ", s.area())
	s = Triangle{
		sideA: 6,
		sideB: 7,
		sideC: 8,
	}
	fmt.Println("Rectangle perimeter is ", s.perimeter(), ",area is ", s.area())
}

在对接口变量进行动态调用时,调用的方法只能是接口中具有的方法。假设Rectangle类型拥有另外的方法getHeight(该方法没有在接口中定义),则接口变量无法调用除接口方法外的其他方法。则在编译时会报错。

你可能感兴趣的:(Golang笔记,Python,python,golang,开发语言)