Đa kế thừa trong Java và Python

Một lớp có thể kế thừa từ nhiều cha. Ví dụ: bạn có thể xây dựng một lớp biểu diễn hình dạng 3D bằng cách kế thừa từ hai hình dạng 2D

class RightPyramid[Triangle, Square]:
    def __init__[self, base, slant_height]:
        self.base = base
        self.slant_height = slant_height

    def what_am_i[self]:
        return 'RightPyramid'

Thứ tự phân giải phương thức [MRO] xác định nơi Python tìm kiếm một phương thức khi có một hệ thống phân cấp các lớp. Sử dụng

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
9 truy cập lớp tiếp theo trong MRO

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]

Nếu bạn kết hợp MRO và tính năng

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
1 để chỉ định các cặp tên-giá trị trong quá trình xây dựng, bạn có thể viết mã chuyển tham số cho các lớp cha ngay cả khi chúng có các tên khác nhau

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area

Nhiều kế thừa có thể trở nên phức tạp một cách nhanh chóng. Một trường hợp sử dụng đơn giản phổ biến trong lĩnh vực này là viết một mixin. Mixin là một lớp không quan tâm đến vị trí của nó trong hệ thống phân cấp mà chỉ cung cấp một hoặc nhiều phương thức tiện lợi

class SurfaceAreaMixin:
    def surface_area[self]:
        surface_area = 0
        for surface in self.surfaces:
            surface_area += surface.area[self]

        return surface_area

class Cube[Square, SurfaceAreaMixin]:
    def __init__[self, length]:
        super[].__init__[length]
        self.surfaces = [Square, Square, Square, Square, Square, Square]

class RightPyramid[Square, Triangle, SurfaceAreaMixin]:
    def __init__[self, base, slant_height]:
        self.base = base
        self.slant_height = slant_height
        self.height = slant_height
        self.length = base
        self.width = base

        self.surfaces = [Square, Triangle, Triangle, Triangle, Triangle]

Đây là những gì bạn nhận được

>>>

>>> cube = Cube[3]
>>> cube.surface_area[]
54

Tải xuống

Slide khóa học [PDF]

896. 4 KB

Xin chúc mừng, bạn đã hoàn thành khóa học. Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Richard Morris trên

Tuyệt vời động lực, có tổ chức, và nhịp độ. Cảm kích nhất

Alex trên

Cảm ơn bạn, đặc biệt là ví dụ về Mixins

Ẩn danh trên

Phải, tôi đã đọc tài liệu nhiều lần, nhưng cách trình bày tài liệu này khiến nó cực kỳ dễ hiểu và rõ ràng - được kết hợp rất tốt. Bây giờ để xem nó 5 lần nữa

rhuang trên

hướng dẫn tuyệt vời. Thanks

ajp4 trên

Lời giải thích tốt nhất mà tôi đã thấy. Cảm ơn bạn

SkyFox trên

Tôi đến với hướng dẫn này để hiểu khái niệm về Mixins. Tôi thực sự hạnh phúc tôi đã có mọi thứ trong vòng chưa đầy 30 phút. Thực sự đánh giá cao sự đơn giản giải thích như vậy

Ryan Cook trên

Tôi thích phần giải thích về “tại sao” trong việc tạo Mix-in và những cạm bẫy tiềm ẩn của đa kế thừa. Tôi thích cách giải thích đơn giản và tốc độ giọng hát được đo lường của bạn. Hãy tiếp tục phát huy

Erikton Konomi trên

hướng dẫn tuyệt vời. Tôi thực sự thích cách ngắn gọn và đi thẳng vào vấn đề của cả ba video, với các ví dụ cụ thể. Tuy nhiên, sự ra đời của mẫu mixin đã tạo ra sự khác biệt cuối cùng. Tôi sẽ sớm tách một số mã tại nơi làm việc với điều này. ] Thanks

ricardoaparicio92 trên

tôi bị lạc

Ricky White Nhóm RP trên

@richardoaparicio92 Bạn đang gặp khó khăn gì vậy?

Liz Schley trên

Điều này là tuyệt vời, vì vậy cảm ơn bạn. Mục đích của tôi là hiểu cách OOP hoạt động trong Python, để tôi có khả năng thiết kế mã tốt khi cần.

Liz Schley trên

Điều tôi thích nhất là phương pháp mro và sử dụng mixin để tránh nhầm lẫn. Chắc chắn là kế hoạch của tôi, nếu có thể vì mã khó hiểu sẽ tạo ra các lỗi tốn thời gian để sửa

graham17 trên

Thực sự hữu ích - một vài đồng xu đã giảm ngay tại đây. Điều duy nhất tôi không nhận được là khối cuối cùng = SACube[3] Tôi nghi ngờ đây là một lỗi - Tôi không thể tìm thấy bất kỳ giới thiệu nào về lớp SACube ở bất cứ đâu - nhưng có lẽ tôi đã bỏ lỡ nó - về tổng thể - một hướng dẫn ngắn gọn tuyệt vời

Christopher Trudeau Nhóm RP trên

Xin chào gham17,

Nắm bắt tốt. Đó là một hiện vật từ phiên bản trước của mã. Chúng tôi sẽ khắc phục sự cố trong thời gian ngắn. Cảm ơn vì đã cho chúng tôi biết. …ct

samsku1986 trên

Trong trường hợp kế thừa đơn lẻ, tại sao lại sử dụng phương thức super[] khi chúng ta có thể gọi phương thức trực tiếp bằng tên lớp ??. Ý tôi là lợi thế là gì?

lớp chữ nhật. def init[bản thân, chiều dài, chiều rộng]. bản thân. chiều dài = chiều dài bản thân. chiều rộng = chiều rộng

def area[self]:
    return [self.length * self.width]

def permiter[self]:
    return [2 * self.length + 2 * self.width]

lớp Hình vuông [Hình chữ nhật]

________số 8_______

Vijay Alagappan trên

Giải thích rõ ràng về các khái niệm như MRO và Mixins. Cảm ơn rất nhiều

Nathan L trên

Bạn đã chỉ ra với

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
98 rằng bạn có thể truy cập
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
08 bằng cách
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
09 hoặc
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
10. Thực hành tốt nhất là gì?

Christopher Trudeau Nhóm RP trên

Chào Nathan,

Nói chung, bạn sử dụng tự. method[] trừ khi có lý do để làm khác. Nếu tôi phải gọi phương thức cha, thì super[] hoặc nếu có một số tình huống cần sự rõ ràng thì tôi sẽ gọi phương thức cha

nj8456 trên

Đã gặp mã này trong “Tạo trình quản lý mô hình tùy chỉnh ở Django” trong Django bằng Sách ví dụ

GIVEN đoạn mã sau

class PublishedManager[models.Manager]:
    def get_queryset[self]:
        return [
            super[PublishedManager, self] 
                .get_queryset[]
                .filter[status='published']
                ]

class Post[models.Model]:
    objects = models.Manager[]
    published_objects = PublishedManager[]
    publish = models.DateTimeField[default=timezone.now]

AND GIVEN

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
13 là Trình quản lý mô hình mặc định cho Bài đăng,

SAU ĐÓ, mã

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
14 tương đương với việc gọi Trình quản lý mặc định Đối tượng -
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
15 từ bên trong một thể hiện của lớp PublishedManager phải không?

Christopher Trudeau Nhóm RP trên

Xin chào nj8456,

Vâng bạn đã đúng. PublishedManager đang ghi đè các mô hình. Giám đốc. get_queryset[], vì vậy trong phần ghi đè đó, nếu bạn gọi self. get_queryset[] bạn sẽ nhận được phiên bản bị ghi đè - một cuộc gọi đệ quy. Việc sử dụng super[] ở đây giúp bạn có được phương thức của cha mẹ

Đây là một mẫu phổ biến trong các mô hình Django. Bạn làm điều gì đó tương tự nếu bạn muốn ghi đè phương thức save[] của Mô hình – gọi cấp độ gốc, để thực hiện những gì nó thường làm, sau đó chạy mã chuyên dụng của bạn

Trong trường hợp PublishedManager. get_queryset[], bạn muốn thực hiện truy vấn giống như truy vấn gốc, nhưng lần này cũng áp dụng bộ lọc. Cha mẹ được gọi, sau đó bộ lọc được áp dụng, sau đó kết quả được lọc được trả về

Ký hiệu ngoặc là một hình thức ngắn để làm

qs = super[Published Manager, self].get_queryset[]
return qs.filter[status='published']

Bởi vì get_queryset[] trả về một QuerySet, nên

fn[]
.other_fn[]
.more_fn[]

mẫu, xâu chuỗi các kết quả của từng mẫu lại với nhau, gọi hàm tiếp theo trên bất kỳ thứ gì được trả về bởi hàm trước đó

Omkar trên

Vì lớp A hoặc X ở đây là lớp cuối cùng trong lớp tiến và lùi, nên chúng ta đã hoàn thành chuỗi. Nhưng điều đó có nghĩa là lớp

def __init__[self,length]:
    Rectangle.__init__[self,length,length] >>>>>>>>>>>>>>>>>>>>calling Rectangle,method[] directly instead of super
    #super[].__init__[length,length]
5 init cũng được gọi ở đây khi cuối cùng trên chuỗi?

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
0

Cuối cùng trong chuỗi hoặc nếu ngay cả khi đây chỉ là một lớp duy nhất gọi nó là

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
9 thì có nghĩa là gọi
def __init__[self,length]:
    Rectangle.__init__[self,length,length] >>>>>>>>>>>>>>>>>>>>calling Rectangle,method[] directly instead of super
    #super[].__init__[length,length]
5 đúng vì nó là lớp cha?

Christopher Trudeau Nhóm RP trên

Xin chào Omkar,

Vâng, đó là một chút khó khăn. Bản thân A sẽ không cần super[]. init[] vì nó super chỉ là lớp Object cơ sở

Trường hợp nó trở nên quan trọng là thông qua chuỗi. Trong trường hợp của lớp Backward, A's super[]. init[] không làm gì cả. Trong trường hợp của lớp Forward, đó là lý do tại sao hàm tạo của X được gọi

super[] gọi lớp tiếp theo trong MRO

Chuỗi hoạt động như thế này

Lùi -> X -> B -> A

Vì vậy, lời gọi của A tới super[]. init[] không làm gì cả. Ngược lại mặc dù

Chuyển tiếp -> B -> A -> X

Trong trường hợp này, không có super[] của A. init[], phương thức init của X sẽ không được gọi

Nếu bạn đang viết các lớp có khả năng bị trộn lẫn hoặc được sử dụng với tính kế thừa, thì cách tốt nhất là gọi “super[]. init[]” trong trường hợp các lập trình viên khác sử dụng lớp của bạn thay đổi thứ tự kế thừa

Omkar trên

Cảm ơn vì lời giải thích rõ ràng. ] Thích thú khi trở thành một phần của cộng đồng này

James trên

Tôi không hiểu lắm phần này của mixin

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
1

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
2

Tại sao họ có những giá trị này? . Thanks

Christopher Trudeau Nhóm RP trên

Chào James,

Ý tưởng ở đây là làm nổi bật chức năng của Mixin. mã phổ biến trên một số lớp mà không nhất thiết phải có kiến ​​thức sâu về lớp

The SurvaceAreaMixin. Phương thức surface_area[] tính toán diện tích bề mặt của hình dạng 3D bằng cách tìm thuộc tính có tên là “các bề mặt” và gọi phương thức area[] cho từng bề mặt, cộng chúng lại với nhau

Khối lập phương có sáu mặt, mỗi mặt là hình vuông. Bằng cách đặt Cube. bề mặt thành sáu Hình vuông, phương thức surface_area[] của mixin sẽ tính toán chính xác diện tích bề mặt của Khối lập phương

RightPyramid bao gồm một đáy hình vuông và bốn cạnh hình tam giác. Nó thể hiện điều này bằng cách đặt thuộc tính “bề mặt” thành [Square, Triangle, Triangle, Triangle, Triangle]

Mixin biết ở mức độ trừu tượng cách tính diện tích bề mặt [bằng cách gọi phương thức area[] trên mỗi hình dạng trong thuộc tính “surfaces”], nhưng không cần biết bề mặt của đối tượng kế thừa mixin là gì

Các chi tiết cụ thể của hình dạng 3D được mô tả trong phần triển khai của lớp [Cube hoặc RightPyramid], nhưng thuật toán tính diện tích bề mặt có thể được tách ra khỏi lớp này thành một lớp mixin chung

Nếu không có mixin, bạn sẽ cần viết các phương thức surface_area[] riêng biệt cho Cube và RightPyramid. Có nó trong mixin có nghĩa là viết và kiểm tra nó ở một nơi duy nhất

Ghani trên

Rất rõ ràng và giải thích tốt

Saul vào

vật liệu tuyệt vời. Tôi có một phân minh nhỏ và một số quan sát hữu ích hy vọng. Xin hãy sửa tôi nếu tôi đi lạc lối. Vào khoảng 7. 18, cần lưu ý rằng hàm tạo của lớp Square nhận cơ sở, độ nghiêng, chiều cao và độ dài làm đối số. Nhưng slant_height không thực sự được bao gồm trong các đối số đó. Nó được ghi lại dưới dạng tham số vị trí trong hàm tạo cho RightPyramid, cùng với cơ sở. Lý do bản thân cơ sở được chuyển lên chuỗi là vì chúng tôi đặc biệt gửi lại cơ sở trong lệnh gọi phương thức

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
19. Chúng tôi không gửi lại slant_height vì nó không được sử dụng bởi bất kỳ siêu lớp nào

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
3

Trên thực tế, nếu chúng tôi đã bao gồm slant_height, một ngoại lệ sau đó sẽ xảy ra khi lệnh gọi đối tượng

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
20 cuối cùng xảy ra

LoạiLỗi. mục tiêu. init[] không nhận tham số

Sử dụng

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
20 theo cách này để xâu chuỗi trên nhiều hệ thống phân cấp thừa kế [bằng cách tuân theo MRO] có nghĩa là chúng tôi không thể có bất kỳ đối số từ khóa không liên quan hoặc không sử dụng nào. Chúng phải được ghi lại bởi các tham số có cùng tên trong hàm tạo ở đâu đó trong chuỗi. Đó là cách duy nhất để chúng bị tiêu thụ và bị loại khỏi từ điển kwargs

Cái khác. Lúc đầu, tôi gặp một chút rắc rối khi gán từ điển kwargs trong hàm tạo cho RightPyramid. Tôi không thể hiểu tại sao chúng ta lại chuyển chiều cao và chiều dài làm đối số với các câu lệnh gán này nhưng sau đó lại chuyển cơ sở làm đối số trong lệnh gọi

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
22. Vâng, có vẻ như những cách tiếp cận này là tương đương. Chúng tôi cũng có thể đã làm một trong những điều sau đây

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
4

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
5

Một lần nữa, xin vui lòng cho tôi biết nếu tôi đang thiếu một cái gì đó. Thanks

Christopher Trudeau Nhóm RP trên

Chào Saul,

Cảm ơn ý kiến ​​​​của bạn

Vào khoảng 7. 18, cần lưu ý rằng hàm tạo của lớp Square nhận cơ sở, độ nghiêng, chiều cao và độ dài làm đối số. Nhưng slant_height không thực sự được bao gồm trong các đối số đó

Tôi tin rằng những gì tôi đang cố gắng truyền đạt là slant_height được chuyển vào nhưng dưới dạng đối số chiều cao. Bạn đã đúng rằng slant_height không được giữ làm đối số được đặt tên

Bạn cũng đúng là bạn phải cẩn thận với những thứ này và những gì được tiêu thụ. Bạn chỉ phải đảm bảo rằng tất cả chúng đều được sử dụng nếu có một lớp ở đâu đó có init[] trống, nếu các hàm tạo của bạn luôn có các đối số

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
23 thì bạn sẽ ổn thôi [anh ấy viết một cách lo lắng mà không cần kiểm tra. ] ]. Điều đó đang được nói, đây là lý do tại sao tôi có xu hướng chỉ thích sử dụng tính kế thừa cho Mixins. Những loại tinh tế này chắc chắn có thể gây ra cho bạn những vấn đề kỳ lạ cả khi biên dịch và thời gian chạy

Lúc đầu, tôi hơi gặp rắc rối khi gán cho từ điển kwargs … Chà, có vẻ như những cách tiếp cận này là tương đương

Đúng, bạn nói đúng. Đã quá lâu kể từ khi tôi viết mã đó, tôi không nhớ tại sao tôi lại làm như vậy. Tôi nghi ngờ nó có liên quan đến cách nó phát triển ra khỏi các phiên bản trước đó. Một trong hai cách tiếp cận hoạt động

Mã hóa vui vẻ

anindo78 trên

Hướng dẫn tuyệt vời về thừa kế

rikhuygen vào

Hướng dẫn tuyệt vời, và giải thích rất rõ ràng

Có một điều tôi không hoàn toàn bị thuyết phục và đó là ví dụ về Mixin. Phương thức

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
24 trong lớp SurfaceAreaMixin sử dụng
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
25 mà bạn đã định nghĩa trong các lớp con. Điều đó nghe có vẻ hơi kỳ lạ đối với tôi. Làm cách nào để tôi biết từ lớp Mixin mà tôi phải xác định các biến thể hiện nào để phương thức không gặp sự cố với AttributeError. Đó có phải là thực hành tốt nhất?

Cảm ơn, Rik

Christopher Trudeau Nhóm RP trên

Xin chào @rikhuygen,

Đúng, đây là một trong những thách thức khi cố gắng dạy mixin và các bài học hướng đối tượng. Việc sử dụng thực sự tốt loại công nghệ này có xu hướng yêu cầu nhiều thông tin cơ bản hơn

Toàn bộ điều "sử dụng hình dạng" để giải thích tính kế thừa OO đã được thử và đúng nhưng có những hạn chế của nó. Ngay cả khi tôi định viết một giao diện đồ họa sử dụng các hình dạng, tôi có thể sẽ không sử dụng hết OO hoặc nếu có, lớp cơ sở sẽ nhẹ hơn nhiều so với được sử dụng trong các giải thích thông thường

Nơi tốt nhất cho những thứ như Mixins là nơi bạn có nhiều quyền độc lập và đang cố gắng thêm một tính năng không cụ thể

Ví dụ: gần đây tôi đã viết một cái gì đó bằng Django yêu cầu một loại định danh đặc biệt. Mã định danh phức tạp hơn một chút so với chỉ một trường và cần một số phương thức. Tất cả những thứ này được đặt bên trong một mixin để bất kỳ đối tượng Django nào cần loại định danh này sẽ trộn nó vào. Vấn đề với việc giảng dạy với loại ví dụ này là sau đó bạn phải giải thích Django là gì và cách nó mô hình hóa các đối tượng và cách điều đó liên quan đến các trường và toàn bộ nội dung khác

Đối với câu hỏi cụ thể của bạn, lượng mã được lưu bằng cách sử dụng mixin này có thể không đảm bảo việc ẩn quá trình triển khai diễn ra theo cách nó được thực hiện. Trong thế giới thực, có lẽ tôi sẽ không viết mã theo cách đó, nhưng sau đó tôi sẽ không có ví dụ về mixin

rikhuygen vào

đủ công bằng, cảm ơn câu trả lời của bạn. [Xin lỗi vì trả lời chậm]

Alex trên

Xin chào, Christoph, tôi rất thích phần hướng dẫn. Bạn có thể vui lòng trả lời 2 câu hỏi sau của tôi không [tương tự như @Saul, nhưng tôi đoán không hoàn toàn]

–1. Việc tạo các biến thể hiện [thay vì chuyển nó qua kwargs] trong phần đầu của lớp Con là một cách làm không tốt, nếu chúng chỉ được sử dụng trong các lớp Cha, như trong phần đầu tiên của ví dụ sau

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
6

–2. Điều gì sẽ là sự khác biệt giữa chuyển biến trong kwargs hoặc chuyển riêng nó thông qua đối số từ khóa?

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
7

Alex trên

Xin lỗi, chỉ là một lưu ý sau, tôi đoán việc trộn lẫn là một tính năng hay, nhưng một nhược điểm [vui lòng sửa cho tôi nếu sai] là nó đang làm ô nhiễm thể hiện với các biến thể hiện không liên quan của lớp RightPyramid chẳng hạn

class A:
    def __init__[self]:
        print['A']
        super[].__init__[]

class B[A]:
    def __init__[self]:
        print['B']
        super[].__init__[]

class X:
    def __init__[self]:
        print['X']
        super[].__init__[]

class Forward[B, X]:
    def __init__[self]:
        print['Forward']
        super[].__init__[]

class Backward[X, B]:
    def __init__[self]:
        print['Backward']
        super[].__init__[]
8

Christopher Trudeau Nhóm RP trên

Chào Alex,

Việc sử dụng

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
1 là trường hợp tổng quát hơn và tôi có thể làm điều đó nếu tôi không cố gắng vạch trần những gì phụ huynh đang làm. Đó là một loại bắt tất cả. Nếu bạn đang xây dựng các cấu trúc mà bạn đang kế thừa trực tiếp, thì không có gì sai khi sử dụng các đối số được đặt tên để thay thế

Một lợi thế của

class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
1 là chuyển sang cấp độ tiếp theo. Ví dụ tốt nhất mà tôi có thể nghĩ đến là trên các đối tượng cơ sở dữ liệu ở Django. họ có một phương thức
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
30 nhận một số tham số. Bạn có thể ghi đè một
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
30 trong một lớp con và chỉ sử dụng các đối số mà bạn cần, nhưng nếu một số lập trình viên khác xuất hiện và cần các đối số mà bạn không khai báo, chúng sẽ bị mắc kẹt. Vì vậy, cách tốt nhất là sử dụng
class Rectangle:
    def __init__[self, length, width, **kwargs]:
        self.length = length
        self.width = width
        super[].__init__[**kwargs]

    def area[self]:
        return self.length * self.width

    def perimeter[self]:
        return 2 * self.length + 2 * self.width

class Square[Rectangle]:
    def __init__[self, length, **kwargs]:
        super[].__init__[length=length, width=length, **kwargs]

class Triangle:
    def __init__[self, base, height, **kwargs]:
        self.base = base
        self.height = height
        super[].__init__[**kwargs]

    def tri_area[self]:
        return 0.5 * self.base * self.height

class RightPyramid[Square, Triangle]:
    def __init__[self, base, slant_height, **kwargs]:
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super[].__init__[base=base, **kwargs]

    def area[self]:
        base_area = super[].area[]
        perimeter = super[].perimeter[]
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2[self]:
        base_area = super[].area[]
        triangle_area = super[].tri_area[]
        return triangle_area * 4 + base_area
1 cho những thứ bạn không sử dụng và chuyển tất cả chúng cho cuộc gọi phụ huynh

Nó thực sự chỉ đi xuống một quyết định thiết kế mặc dù

Đối với câu hỏi của bạn về các lớp bị ô nhiễm, vâng, trong trường hợp này, đó là một tác dụng phụ đáng tiếc. Hình dạng là một phép loại suy tốt để dạy các khái niệm thừa kế, nhưng chỉ là một phép loại suy. Các ví dụ tốt nhất về mixin thường đòi hỏi sự hiểu biết sâu hơn về các hệ thống khác hơn là hữu ích khi giảng dạy

Mixin được sử dụng phổ biến nhất của tôi lại nằm trong không gian Django. Tôi muốn có dấu ngày/giờ trên tất cả các bảng cơ sở dữ liệu để theo dõi thời điểm một hàng được tạo và cập nhật lần cuối. Nó có thể hữu ích khi gỡ lỗi các vấn đề sản xuất. Như vậy, mixin có các trường này trong đó và chỉ được thêm vào bất kỳ lớp dữ liệu nào tôi tạo. Vì các trường này và bất kỳ phương thức liên quan nào đều độc lập với các lớp trộn chúng vào nên không có vấn đề ô nhiễm. Tuy nhiên, việc giảng dạy với ví dụ này là một vấn đề, bởi vì bạn không thể chạy mã trừ khi bạn đã thiết lập tất cả các công cụ Django, và do đó, bạn sẽ phải sử dụng các phép loại suy tầm thường

Với rất nhiều thứ này, nó bắt nguồn từ việc thực hành. Ngay cả khi thực hành, có rất nhiều lần tôi gặp khó khăn với một quyết định thiết kế mà tôi đã đưa ra và sau đó phải quay lại và thay đổi nó thành một thứ khác sau đó. Chào mừng bạn đến với niềm vui viết mã. ]

Đa kế thừa có khả thi trong Python không?

Có, Python hỗ trợ đa kế thừa . Giống như C++, một lớp có thể được bắt nguồn từ nhiều lớp cơ sở trong Python. Điều này được gọi là Đa kế thừa.

Tại sao đa kế thừa được hỗ trợ trong Python mà không phải trong Java?

Lý do đằng sau điều này là để tránh sự mơ hồ . Hãy xem xét trường hợp lớp B mở rộng lớp A và lớp C và cả lớp A và C đều có cùng một phương thức display[]. Bây giờ trình biên dịch java không thể quyết định nên kế thừa phương thức hiển thị nào. Để ngăn chặn tình trạng như vậy, nhiều kế thừa không được phép trong java.

Kế thừa trong Java và Python khác nhau như thế nào?

Để điều này hoạt động trong java, đối tượng được thay thế phải kế thừa từ loại dự kiến ​​hoặc triển khai giao diện dự kiến. Trong python, điều đó hoàn toàn không cần thiết;

Tại sao Python cho phép đa kế thừa?

Kế thừa là cơ chế để đạt được khả năng sử dụng lại mã vì một lớp [lớp con] có thể lấy thuộc tính của lớp khác [lớp cha] . Nó cũng cung cấp tính bắc cầu tức là. nếu lớp C kế thừa từ P thì tất cả các lớp con của C cũng kế thừa từ P.

Chủ Đề