Comments (15)
from learning_list.
from learning_list.
最简单的继承
class Person:
def walk(self):
print("Walk.Walk.Walking.")
def sleep(self):
print("Sleep.Sleep.Sleeping...")
class Male(Person):
def __init__(self):
self.sex = "male"
def fight(self):
print("Male fights for female.")
class Female(Person):
def __init__(self):
self.sex = "female"
def wait(self):
print("Female waits for male")
Sam = Male()
Lisa = Female()
Sam.walk()
Lisa.sleep()
Sam.fight()
Lisa.wait()
from learning_list.
from learning_list.
继续扩展面向对象
- 菱形继承
- 元类
from learning_list.
Python 解决菱形继承的方法:MRO(深度优先,从左到右,然后倒序去重)
- 经典类(classic class)的深度遍历(最粗糙,3.0 以后不再支持)
- Python 2.2 的新式类(new-style class)预计算(mro 属性),依旧无法防止程序员写出二义性继承,如下图:
- Python 2.3 的新式类的 C3 算法。它也是 Python 3 唯一支持的方式。会直接对上图二义性继承抛出异常。
from learning_list.
元类: A metaclass is the class of a class.
- Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. - A class is an instance of a metaclass.
- type is the usual metaclass in Python.
- type is itself a class, and it is its own type.
- You won't be able to recreate something like type purely in Python, but Python cheats a little.
- To create your own metaclass in Python you really just want to subclass type.
“Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why).”
— Tim Peters
Still, understanding Python metaclasses is worthwhile, because it leads to a better understanding of the internals of Python classes in general. You never know: you may one day find yourself in one of those situations where you just know that a custom metaclass is what you want.
from learning_list.
元类精彩示例
class Meta(type):
meta_cls_attr = "meta_cls_attr"
def __new__(meta_cls, name, bases, dct):
cls = super().__new__(meta_cls, name, bases, dct)
cls.cls_attr = "cls_attr"
return cls
class Foo(metaclass=Meta):
pass
print(hasattr(Foo, 'cls_attr'), Foo.cls_attr)
print(hasattr(Foo, 'meta_cls_attr'), Foo.meta_cls_attr)
from learning_list.
def class_decorator(cls):
class NewClass(cls):
attr = 100
return NewClass
@class_decorator
class Too:
pass
print(hasattr(Too, 'attr'))
from learning_list.
结论:大部分情况下都不需要定制元类,但了解元类的工作原理,在一定程度上能帮自己更好的掌握 Python 类的工作机制:
- object 是一个继承自元类 type 的类对象
- 在普通类的声明语句执行执行之时,会执行 object 的 new 和 init 方法,初始化一个类对象,类中各个值属性以及函数属性,都是在这个过程中产生的。
- 有了普通的类对象之后,类的继承关系早已确定下来,实例化时对程序可见的部分主要是执行类对象中的 init 方法,初始化一些实例属性,有需要时也可以执行一些特定的方法,生成一个类实例。
- 类对象中的函数是可以直接可以用在实例身上的
- 元类中的 cls 指将来的类对象,类对象中的 self 指将来的类实例
- 因此,也就有了三种类属性(值(类可以访问,实例也可以访问),方法(类自己的方法),函数(会成为类实例的方法))
from learning_list.
What is Type?(在贴近硬件实现的层次上)
- It determines how much memory is needed for a data object.(类型最终要落在具体的物理内存中)
- It determines how the bits in memory are interpreted. (A long and a float might use the same number of bits in memory, but they are translated into numeric values differ- ently.)(数据最终全是 0 1 序列,关键要看以什么规则诠释数据结构)
- It determines what operations, or methods, can be performed using the data object.(数据除了要落在物理级别的存储,以及对应的诠释规则外,还应该具备可操作性)
from learning_list.
What Is an Interface?
An interface is a shared framework for interactions between two systems.
from learning_list.
An ADT describes a data type in a general fashion, without bringing in language or implementation details.
The class concept is a nice match to the ADT approach.
from learning_list.
多态:父类调用子类方法(这当然是表象,但自己还未能找到为什么会有多态)
#include<iostream>
using namespace std;
// 基类对象
class Base
{
public:
//有virtual关键字,运行时多态
virtual void f(float x)
{
cout<<"Base::f(float)"<< x <<endl;
}
//无viratul关键字,不会发生运行时多态
virtual void g(float x)
{
cout<<"Base::g(int)"<< x <<endl;
}
void h(float x)
{
cout<<"Base::h(float)"<< x <<endl;
}
};
// 衍生类对象
class Derived : public Base
{
public:
virtual void f(float x)
{
cout<<"Derived::f(float)"<< x <<endl; //多态、覆盖
}
virtual void g(int x)
{
cout<<"Derived::g(int)"<< x <<endl; //多态、覆盖
}
//子类与父类的函数同名,无virtual关键字,则为隐藏
void h(float x)
{
cout<<"Derived::h(float)"<< x <<endl; //隐藏
}
};
int main(void)
{
Derived d; //子类
Base *pb = &d; //基类指针指向子类
Derived *pd = &d; //子类指针指向自己
// Good : behavior depends solely on type of the object
pb->f(3.14f); // Derived::f(float) 3.14 调用子类,多态
pd->f(3.14f); // Derived::f(float) 3.14 调用子类
pb->g(3.14f); // Base::g(float) 3.14 签名不一样 不调用子类
pd->g(3.14f); // Derived::g(int) 3 调用子类
// Bad : behavior depends on type of the pointer
pb->h(3.14f); // Base::h(float) 3.14 无多态,调用自己的
pd->h(3.14f); // Derived::h(float) 3.14 无多态,调用自己的
return 0;
}
from learning_list.
指向派生类的指针类型与指向基类的指针类型是兼容的(反之不成立!)。这个简单的特性是C++ 多态性的基础。
什么意思呢?一个动物类型的引用,可以指向猫,也可以指向狗,还可以指向猪,因为一个动物本来就有可能是猫,是狗或是猪。就像一个人,可以是一个男人或者也可以是女人。
这可能有点绕,但这样有一个好处,就是我可以声明一个动物向量,里面的成员既可以是猫,也可以是狗。
这样是不是就有点意思了?
下面用代码表示一下。
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
// Animal Class
class Animal
{
public:
virtual void scream()
{
cout << "Animal is screaming..." << endl;
}
};
// Cat Class
class Cat : public Animal
{
public:
virtual void scream()
{
cout << "Cat is screaming..." << endl;
}
};
// Dog Class
class Dog : public Animal
{
public:
virtual void scream()
{
cout << "Dog is screaming..." << endl;
}
};
// Pig Class
class Pig : public Animal
{
public:
virtual void scream()
{
cout << "Pig is screaming..." << endl;
}
};
int main(void)
{
Cat cat1;
Animal *a1 = &cat1;
a1->scream();
Dog dog1;
Animal *a2 = &dog1;
a2->scream();
Pig pig1;
Animal *a3 = &pig1;
a3->scream();
vector<Animal*> animal_poly;
animal_poly.push_back(a1);
animal_poly.push_back(a2);
animal_poly.push_back(a3);
animal_poly[0]->scream();
animal_poly[1]->scream();
animal_poly[2]->scream();
return 0;
}
Python Tutor C++ polymorphysm 应用演示
from learning_list.
Related Issues (20)
- 给函数式程序员的 Hack Pipe:我如何学着停止担忧并爱上那顶小帽子 HOT 1
- 一文说透 TypeScript 的增删查改
- 重温 React hook 基本原理
- rust 中消失的三元去了哪里?
- 如何判断类型中是否有必填字段
- automate chrome by script kit
- applescript 踩坑经验
- hammerspoon 添加自定义菜单,执行 shell 脚本
- karabiner multitouch_extension
- 我的 Mac 使用实践总结
- 活久见之 JS 新见闻:return 写不写还是有关键区别的。
- Rust trait vs TypeScript interface
- React Final Form useFormValuesWatch
- data fetch in react
- type safe useParams
- finally, learn how generate struct with builtin function in Zig
- zig code: auto git push, find suitable target branch and open merge url in browser
- bun preloader for test
- depth protection and loose union
- 初步建立起 RSC 的直观体验 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from learning_list.