Tag: class

  • Class trong Python

    Class trong Python

    Class trong Python

    Python là một ngôn ngữ lập trình hướng đối tượng. Hầu hết mọi thứ trong Python đều là một đối tượng, với các thuộc tính properties và phương thức methods.

    Lớp Class trong Python kí hiệu là class được hiểu như là một bản mẫu, bản mô tả về các đối tượng nào đó. Class (lớp, loài) chính là một định nghĩa, chứa tất cả các thông tin bao gồm thuộc tính – properties và hành vi – method, function của mọi cá thể (đối tượng – object) trong loài đó.

    Ví dụ, chúng ta định nghĩa lớp car thì lớp này sẽ phải bao gồm tất cả những thông tin, đặc điểm chung mà mọi chiếc ô tô đều có:

    • các thuộc tính: fuel – loại nguyên liệu sử dụng, maxspeed – tốc độ tối đa…
    • các hàm, phương thức: refuel() – nạp nhiên liệu, getFuel() – lấy mức nhiên liệu hiện tại, setSpeed() – thiết lập vận tốc là bao nhiêu, getSpeed() – lấy vận tốc hiện tại của xe, drive() – lái xe…

    lớp class trong python

    Khi đó, giả sử myCar là một object (đối tượng) của class car thì myCar phải có đầy đủ các đặc điểm của lớp car với những thông số cụ thể. Chẳng hạn myCar.fuel có giá trị là xăng, myCar.maxSpeed bằng 18o km/h, khi gọi hàm myCar.getFuel() sẽ trả về mức nhiên liệu hiện tại của myCar

    Đối tượng (Object) chỉ đơn giản là một tập hợp các dữ liệu (các biến) và các phương thức (các hàm) hoạt động trên các dữ liệu đó. Và, lớp (class) là một kế hoạch chi tiết cho đối tượng.

    Xem thêm 15 Cuốn sách học Python miễn phí

    Nếu bạn thấy khó hiểu thì nên nhớ rằng từ bản thân từ class có nghĩa là loài, lớp. Nói đến loài mèo, chúng ta đều biết rằng tất cả các con mèo đều có các đặc điểm như màu lông, màu mắt, chiều dài, cân nặng… và các hành động như kêu meo meo, dụi lông vào chân, kêu gừ gừ… Do đó, chúng ta có thể dùng class LoaiMeo để mô tả những đặc điểm này của loài mèo. Nhưng, đối với mỗi một con mèo cụ thể thì từng đặc điểm trên lại có các giá trị cụ thể khác nhau. Chẳng hạn con mèo Milu của tôi thì màu xám, cân nặng 2 kí, mắt xanh… còn con mèo Mimi của bạn thì lại màu trắng, cân nặng 3 kí và mắt nâu.

    class lop trong Python

    Các khái niệm trong class

    • Instance là một hiện thực cụ thể của một lớp, có thể gọi là thực thể (cá thể). Chẳng hạn, với lớp LoaiMeo kể trên thì Milu là một instance của LoaiMeo.
    • Methods: Hàm, phương thức của một class.
    • Data members: Biến chứa dữ liệu gồm: class variable và instance variable.
      • Class variable: Biến dùng chung cho tất cả các đối tượng của lớp, được định nghĩa trong lớp mà không nằm trong methods (hàm thực thi) nào cả. Các biến này không được sử dụng thường xuyên.
      • Instance variable: Biến được định nghĩa bên trong method và chỉ thuộc về các instance (đối tượng thực thể của lớp).

    Khai báo Class trong Python

    Khai báo lớp trong Python sử dụng từ khóa class, theo sau là tên của lớp, thường bắt đầu bằng kí tự viết hoa và cuối cùng là kí tự :

    Dòng tiếp theo, thường là comment sử dụng cặp ngoặc ''' gọi là docstring – một mô tả ngắn gọn về lớp. Docstring này không bắt buộc nhưng khuyến khích sử dụng.

    Tiếp theo là các thuộc tính và các hàm, phương thức của lớp. Cấu trúc chung như sau:

    class TenLop:
        '''Mô tả về class'''
        <các trường dữ liệu (data field)>
        <các hàm, phương thức>

    Ví dụ, khai báo lớp MyClass với thuộc tính a = 5, chúng ta viết như sau:

    class MyClass:
        '''Đây là docstring. Một lớp mới vừa được khai báo.'''
        a =5

    Class tạo ra một local namespace mới trở thành nơi để các thuộc tính của nó được khai báo. Thuộc tính có thể là hàm hoặc dữ liệu.

    Tạo một đối tượng trong Python

    Để tạo một đối tượng object của class, chẳng hạn lớp MyClass chúng ta cần một biến để lưu đối tượng này và dùng phép gán, theo sau là lời gọi MyClass()

    class MyClass:
        '''Đây là docstring. Một lớp mới vừa được khai báo.'''
        a =5
    foo = MyClass()

    Truy cập đến các thuộc tính, method của class

    Để truy cập đến các thuộc tính, hàm, phương thức của lớp, chúng ta sử dụng dấu chấm . sau tên lớp, tên đối tượng và theo sau là tên thuộc tính, tên hàm. Ví dụ, với lớp MyClass ở trên, để truy cập đến thuộc tính a, chúng ta dùng câu lệnh MyClass.a hoặc foo.a

    class MyClass: 
      '''Đây là docstring. Một lớp mới vừa được khai báo.''' 
      a =5
    foo = MyClass()
    
    print(foo.a) //kết quả 5
    print(MyClass.a) //kết quả 5

    Chúng ta có thể thay đổi giá trị cho các thuộc tính của một đối tượng trong class sử dụng phép gán giá trị mới cho thuộc tính đó. Chẳng hạn, trong ví dụ trên, chúng ta muốn a nhận giá trị 7 thì làm như sau

    <pre class="EnlighterJSRAW" data-enlighter-language="python">class MyClass: 
      '''Đây là docstring. Một lớp mới vừa được khai báo.''' 
      a =5
    foo = MyClass()
    
    print(foo.a) //kết quả 5
    foo.a = 7
    print(foo.a)//kết quả 7
    
    print(MyClass.a) //kết quả 5

    Lưu ý rằng, cùng là thuộc tính a nhưng gắn với những đối tượng khác nhau thì sẽ là những đối tượng khác nhau. Chẳng hạn, cùng thuộc về lớp ConNguoi, nhưng mỗi con người cụ thể sẽ có những tên, tuổi, đặc điểm không giống nhau.

    Xóa bỏ thuộc tính và đối tượng

    Ngoài việc đọc các giá trị, ghi các mới cho các trường của class hoặc gọi các hàm, phương thức của class, chúng ta có thể xóa các thuộc tính, các phương thức của một lớp, hoặc xóa một đối tượng của lớp. Để làm việc này, chúng ta sử dụng lệnh del theo sau là tên lớp và tên thuộc tính, phương thức:

    >>> class MyClass:
    ...   a = 5
    ...
    >>> foo = MyClass()
    >>> foo.a
    5
    >>> foo.a = 10 //gán giá trị 10 cho trường a của đối tượng foo
    >>> foo.a
    10
    >>> del foo.a //xóa giá trị trong trường a của đối tượng foo
    >>> foo.a
    5
    >>> del MyClass.a //xóa trường a của lớp MyClass
    >>> foo.a
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'MyClass' object has no attribute 'a'

    Các phương thức method của class

    Một class ngoài các thuộc tính properties còn có các hàm, phương thức methods để thực hiện những công việc nào đó. Như trong lớp car ở đầu bài viết thì các phương thức chính là refuel(), getFuel(), setSpeed()

    Constructor Hàm __init__() trong Python

    Tất cả các lớp đều có một hàm được gọi là __init __ (), hàm này luôn được thực thi mỗi khi một đối tượng của lớp được khởi tạo. Chúng ta sử dụng hàm __init __ () để cung cấp các giá trị khởi tạo cho các thuộc tính hoặc các thao tác khác cần thực hiện khi đối tượng được tạo.

    Ví dụ sau, chúng ta tạo một lớp có tên Person, sử dụng hàm __init __ () để gán giá trị cho trường tên name và tuổi age:

    class Person:
      def __init__(self, name, age):
        self.name = name
        self.age = age
    p1 = Person("PHƯƠNG", 34)
    
    print(p1.name)
    print(p1.age)

    Self trong Python là gì?

    Các hàm function, phương thức method trong mỗi lớp khi khai báo thì đều có tham số self, tham số self là một tham chiếu đến thể hiện hiện tại của lớp. Khi gọi thì bạn không cần vì Python sẽ tự động truyền instance vào biến self đó. Như trong ví dụ sau, biến p1 khi được gọi hàm sayHeloo thì self sẽ được tham chiếu đến chính biến p1.

    class Person:
      def __init__(self, name, age):
        self.name = name
        self.age = age
    
      def sayHeloo(self):
        print("Hello my name is " + self.name)
    
    p1 = Person("PHUONG", 34)
    p1.sayHeloo()

    Bạn hoàn toàn có thể sử dụng từ khác để thay thế từ self, chẳng hạn từ yours 🙂

    class Person:
      def __init__(yours, name, age):
        yours.name = name
        yours.age = age
    
      def sayHeloo(mine):
        print("Hello my name is " + mine.name)
    
    p1 = Person("PHUONG", 34)
    p1.sayHeloo()

    Static Methods

    Static Methods (phương thức tĩnh) trong Python cũng tương tự như các phương thức chúng ta gặp từ đầu bài viết đến giờ, sự khác biệt duy nhất là phương thức tĩnh được liên kết với một lớp chứ không phải các đối tượng của lớp đó. Nghĩa là bạn sẽ gọi đến static method bằng tên class chứ không phải bằng tên đối tượng.

    Điều này có nghĩa là một phương thức tĩnh có thể được gọi mà không cần đối tượng cho lớp đó. Điều này cũng có nghĩa là các phương thức tĩnh không thể sửa đổi trạng thái của một đối tượng vì chúng không bị ràng buộc với nó.

    Cách tạo phương thức tĩnh trong Python

    • Sử dụng hàm staticmethod() để biến một phương thức bình thường thành phương thức tĩnh;
    • Sử dụng từ khóa @staticmethod trước khi khai báo phương thức.

    Dưới đây là ví dụ về cách tạo phương thức tĩnh thứ nhất:

    class Calculator:
        def addNumbers(x, y):
            return x + y
    
    # create addNumbers static method
    Calculator.addNumbers = staticmethod(Calculator.addNumbers)
    
    print('Product:', Calculator.addNumbers(15, 110))

    hoặc cách thứ hai

    class Calculator:
        # create addNumbers static method
        @staticmethod
        def addNumbers(x, y):
            return x + y
    
    print('Product:', Calculator.addNumbers(15, 110))

    Trong bài viết tiếp theo, chúng ta sẽ lần lượt tìm hiểu các chủ đề khác về class trong Python như tính kế thừa, operator overloading, data encapsulation và private attributes… Mời các bạn đón xem.

  • Class in Dart / Flutter

    Class in Dart / Flutter

    Class in Dart/Flutter

    What is class in Dart?

    • In object-oriented programming, a class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods).
    • We can assume a class as a sketch (prototype) or a car. It contains all the details about model name, year, features, price, etc. Based on these properties of the car, we can build the car. Here the car is an object.
    • There can be many cars so we can create many objects of cars to access all the properties.

    what is class in dart flutter

    Benefit of object-oriented programming

    • Modularity: The source code of an object can be maintained individually and can hide from the other object’s source code.
    • Data – hiding: Using oops programming, the details of the internal functionality of code are hidden from the others. For example – Users only interact with the application, but they don’t familiar with the internal implementation.
    • Reusability: We don’t need to write the same code again and again. We can use the object of class multiple times in our program.
    • Pluggability and debugging easy: If any object is creating a problem in our program, and then we can replace it in our program and plug the new object as its replacement. The oops code can be easy to debug.

    Defining a Class in Dart

    Dart provides class keyword followed by a ClassName is used to define a class; all fields and functions are enclosed by the pair of curly braces {}.

    class ClassName {
      <fields/properties>
      <getters/setters>
      <constructors>
      <functions>
    }
    • <fields/properties> any variable declared in a class, represent data pertaining to objects.
    • <getters/setters> initialize and retrieve the values of the fields of a class
    • <constructors> responsible for allocating memory for the objects of the class.
    • <functions> represent actions an object can take

    class in dart

    Creating Instance of the class

    • To create an instance of the class, use the new keyword followed by the class name.

    var object_name = new ClassName([arguments])

    • The new keyword is responsible for instantiation. Starting from Dart 2, the keyword new can be omitted.
    • The right-hand side of the expression invokes the constructor.
    • The constructor should be passed values if it is parameterized.

    Libraries and visibility

    • a library referring to the code inside a file with the .dart extension
    • to use that particular library, you have to reference its content with the import keyword
    • using the as keyword if have two different libraries have implemented a class with the same name
    • selectively import or exclude types using the show and hide keywords

    Class Constructors

    A constructor is a special function of the class that is responsible for initializing the variables of the class. Dart defines a constructor with the same name as that of the class. A constructor is a function and hence can be parameterized. However, unlike a function, constructors cannot have a return type.

    👉Named and positional parameters in Dart

    Class_name(parameter_list) {
    //constructor body
    //.............
    }
    • If your class doesn’t define a constructor, the compiler automatically adds a default constructor with no parameters and an empty body.
    • The “initializing formal” using this keyword, more readable and it initializes the variables immediately
    • With null safety, a named argument with a non-nullable type must either have a default or be marked with the new required keyword. Otherwise, it wouldn’t make sense for it to be non-nullable, because it would default to null when not passed.
    • With the “initializing formal” you can still declare a body to perform additional setup for the class, constructors cannot have a return type.
    • If you don’t declare a constructor, a default no-argument constructor is provided for you.

    Initializer list

    • When using the initializing formal approach, the names of the variables must match the ones declared in the constructor.
    • If you wanted to keep fields private but with a different name in the constructor, use an initializer list
    class Test {
    int _secret;
    double _superSecret;
    Test(int age, double wallet)
    : _secret = age,
    _superSecret = wallet;
    }

    Named Constructors

    Named constructors are generally used to implement a default behavior the user expects from your class. They are the only alternative to have multiple constructors since Dart has no method overload.

    Class_name.constructor_name(param_list)

    Redirecting constructors

    Sometimes you might have a constructor that does almost the same thing already implemented by another one. It may be the case to use redirecting constructors in order to avoid code duplication.

    Factory constructors

    • The factory keyword returns an instance of the given class that’s not necessarily a new one. It can be useful when:
      • you want to return an instance of a subclass instead of the class itself,
      • you want to implement a singleton (the Singleton pattern),
      • you want to return an instance from a cache.
    • Factory constructors are like static methods and so they don’t have access to this. There cannot be together a factory and a “normal” constructor with the same name.

    static variables and methods

    • The static keyword can be applied to the data members of a class, i.e., fields and methods. A static variable retains its values till the program finishes execution. Static members are referenced by the class name.
    • The static variables and methods are part of the class instead of a specific instance.
    • The static keyword is used for a class-level variable and method that is the same for every instance of a class, this means if a data member is static, it can be accessed without creating an object.
    • The static keyword allows data members to persist values between different instances of a class.
    • There is no need to create a class object to access a static variable or call a static method: simply put the class name before the static variable or method name to use them.

    The this keyword

    The this keyword refers to the current instance of the class. Here, the parameter name and the name of the class’s field are the same. Hence to avoid ambiguity, the class’s field is prefixed with the this keyword.

    Accessing Attributes and Functions

    A class’s attributes and functions can be accessed through the object. Use the “.” dot notation (called as the period) to access the data members of a class.

    //accessing an attribute
    obj.field_name
    //accessing a function
    obj.function_name()

    Cascade notation

    • The cascade notation (..) in Dart allows you to make a sequence of operations on the same object (including function calls and field access).
    • This notation helps keep Dart code compact and removes the need to create temporary variables to store data.

    Encapsulation (Access modifiers)

    • In Java, we can use public, protected, and private keywords to control the access scope for a property or method. However, Dart doesn’t provide that
      kind of keywords. Instead, you can use _ (underscore) at the start of the name to make a data member of a class becomes private.
    • In Dart, the privacy is at library level rather than class level. It means other classes and functions in the same library still have the access. So, a data member is either public (if not preceded by _) or private (if preceded by _)

    Getters and Setters

    • Getters and Setters, also called as accessors and mutators, allow the program to initialize and retrieve the values of class fields respectively. Getters or accessors are defined using the get keyword. Setters or mutators are defined using the set keyword.
    • A default getter/setter is associated with every class. However, the default ones can be overridden by explicitly defining a setter/ getter. A getter has no parameters and returns a value, and the setter has one parameter and does not return a value.

    Class Inheritance

    • Dart supports the concept of Inheritance which is the ability of a program to create new classes from an existing class. The class that is extended to create newer classes is called the parent class/super class. The newly created classes are called the child/sub classes.
    • A class inherits from another class using the extends keyword. Child classes inherit all properties and methods except constructors from the parent class.

    Types of Inheritance

    • Inheritance can be of the following three types:
    • Single – Every class can at the most extend from one parent class.
    • Multiple – A class can inherit from multiple classes. Dart doesn’t support multiple inheritance.
      Multi-level – A class can inherit from another child class.

    Class Inheritance and Method Overriding

    • Method Overriding is a mechanism by which the child class redefines a method in its parent class.

    super keyword

    • The super keyword is used to refer to the immediate parent of a class.
    • The super keyword can be used to refer to the super class version of a variable, property, or method.

    super and constructors

    Every subclass in Dart automatically tries to call the default constructor of the superclass. If there isn’t one, you must call the superclass constructor
    manually in the initializer list.

    Abstract class

    • The abstract keyword defines a class that cannot be directly instantiated: only its derived classes can. An abstract class can define one (or more)
      constructors as usual.
    • Usually abstract classes contain abstract methods which can be defined putting a semicolon (;) instead of the body. You cannot define an abstract
      method in a class that’s not been marked with the abstract modifier.
    • If your class contains at least one method with no body, then it must be abstract and the children must provide an implementation.

    Interfaces

    • In contrast to other programming languages, Dart does not have an interface keyword and you have to use classes to create interfaces. Your class can
      implement more than a single interface.
    • The keyword is implements and, differently from a regular subclass, here you must override every method defined by the class/interface.
    • In Dart when you use the term interface you are referring to a class that is going to be used by others along with implements because it only provides method signatures. The concept is the same you can find in Java, Delphi or C# with the only difference that Dart doesn’t have a dedicated keyword.
    • While extends can be used with only one class, implements works with one or more classes, which you should treat as interfaces (methods with no body).

    extends vs implements

    • When you use class B extends A {} you are NOT forced to override every method of class A. Inheritance takes place and you can override as many methods as you want. This is the typical OOP inheritance that can be used when you want to add some missing features in a subclass.
    • When you use class B implements A {} you must override every method of class A. Inheritance does NOT take place because methods just provide an API, a “skeleton” that the subclass must concretize.
    • Interfaces are useful when you don’t want to provide an implementation of the functions but just the API. It’s like if the interface was wall socket and the class was the plug that adapts to the holes. While multiple inheritance is not allowed, you can extends a class and implements more than one.

    Mixins

    • a mixin is simply a class with no constructor that can be “attached” to other classes to reuse the code without inheritance
    • mixins like a “copy/paste” tool to reuse methods

    override operators

    • Operator overloading gives the possibility to customize the usage of operators in your classes.
    • Arithmetic operators like +, -, *, or /.
    • Relational operators such as >=, <=, > or <.
    • Equality operators like != and ==

    callable classes

    There is a special call() method which is very closely related to an operator overload because it allows classes to be called like if they were functions with
    the () operator.