图片 6

面向对象编程,深入理解原型

属性的get方法没找到,可能是CourseEntity类中对应属性没有get方法,如果有就看CourseEntity.hbm.xml属性名称,应该是写错了不和CourseEntity类中属性名相同,修改一下就行了。

2.给对象添加属性和方法

给通过构造函数创建的对象添加属性和方法:在函数内部通过this给构造函数返回的对象添加属性。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
var person1 = new Person();

通过构造函数的prototype属性给对象添加属性和方法,这种方式添加的属性和方法会被所有的对象实例共享。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    return this.name;
}
Person.prototype.breathes = '空气';
var person1 = new Person('张三', 20);
var person2 = new Person('李四', '21');
person1.sayName();

注意:一定要前在原型中定义方法和属性,然后再使用:

person2.eat();
Person.prototype.eat = function() {
    console.log('吃饭啦');
}

图片 1

注意:原型对象中属性和对象自己的属性是有区别的,对象自己属性默认是可配置可枚举的,而我们在原型中添加的属性是不可配置的,但确是可枚举。

function Person (name, age) {
      this.name = name;
      this.age = age;
    }
    Person.prototype.sayName = function() {
        return this.name;
    }
    Person.prototype.breathes = '空气';

    var person1 = new Person('张三', 20);

    delete person1.sayName;

    console.log(person1.sayName())   // '张三'

    for(propName in person1){
      console.log(propName)       // name age sayName breathes
    }
class people:
    name = 'jack'

p = people()
p.age =12
print p.name    #正确
print p.age     #正确

print people.name    #正确
print people.age     #错误

1.prototype:

只要我们定义一个函数,prototype作为函数的属性存在了,它的初始值是一个对象。

function Person () {

}
Person.prototype

图片 2

  在类中可以根据需要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,,一般以名为’self’的变量作为该参数(用其他名称也可以),而且需要作为第一个参数。下面看个例子:

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。所有原型对象都会自动获得一个consturctor属性,这个属性指向prototype属性所在函数的指针。Person.prototype.constructor 指向Person。通过这个构造函数可以继续为原型对象添加其他属性和方法.

  关于面向对象编程暂时就讲这么多了,其他关于类的继承和方法重载这些内容将在后面继续讲解。

4.hasOwnProperty()方法和in操作符的区别

判断对象中是否存在某个属性,除了使用in操作符,还可以使用hasOwnProperty()方法。hasOwnProperty()方法只在对象自己的属性列表中搜索;而in操作符,先在对象自己的属性列表中查找,如果找不到,接着去原型对象的属性列表中查找。

function Person (myname, myage) {
  this.name = myname;
  this.age = myage;

}
Person.prototype.sayName = function() {
  console.log(this.name)
}
var person1 = new Person('小明', 18, '女');
// 使用hasOwnProperty()方法
console.log(person1.hasOwnProperty('name'))     // ture
console.log(person1.hasOwnProperty('sayName'))  // false
// 使用in操作符
console.log('sayName' in person1)               // true

  提示找不到该属性,因为私有属性是不能够在类外通过对象名来进行访问的。在Python中没有像C++中public和private这些关键字来区别公有属性和私有属性,它是以属性命名方式来区分,如果在属性名前面加了2个下划线’__’,则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。

3.覆盖原型中属性

如果对象出现了和原型对象中同名的属性或方法,原型的属性和方法会被覆盖掉。这是因为,我们在访问对象的属性或方法时,优先在对象自己的属性列表中查找,如果找到的话,就使用自己的属性,如果找不到的,就去原型对象中查找。

在下面的示例中,原型对象中sayName方法被对象自己的sayName方法遮挡住了,所以最终调用的是对象自己的sayName方法。

function Person (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function() {
    return this.name;
}

var person1 = new Person('李四', 20);
person1.sayName = function() {
    console.log('对象自己的sayName方法')
}
person1.sayName();      // '对象自己的sayName方法'

  虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程。下面就来了解一下如何在Python中进行对象编程。

7.扩展(增强)内置的构造函数创建的对象

内置的构造函数有ArrayStringObjectFunction等,我们可以通过改变原型对象的方式增强由这些构造函数创建的对象。

例如,给数组添加一个inArray()方法,用于判断数组中是否包含某个元素:

Array.prototype.inArray = function (ele) {
for (var i = 0; i < this.length; i++) {
  if(this[i] === ele) {
    return true;
  }
}
return false;
};
var colors = ['red', 'green', 'blue'];
console.log(colors.inArray('red'));        // true
console.log(colors.inArray('purple'));     // false

 

  在前面的例子中我们接触到的就是类属性,顾名思义,类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。

5.isPrototypeOf()方法

该方法是用来判断一个对象是否是另一个对象的原型。例如:

var monkey = {
    feeds: '香蕉',
    breathes: '空气'
}

function Human (name) {
    this.name = name;
}

Human.prototype = monkey;
接下来我们来判断monkey对象是否是Human原型:

var person1 = new Human('李四');
monkey.isPrototypeOf(person1)
验证person1的原型是否是monkey

console.log(Object.getPrototypeOf(person1))
console.log(Object.getPrototypeOf(person1) === monkey)

  下面来看一下类方法、实例方法和静态方法的区别。

6.proto

我们先前讲过,当我们访问一个当前对象中没有的属性时,会去prototype对象中查找。

var developer = new Human('李四');
developer.feeds = '大米饭';
developer.hacks = 'JavaScript';

developer.hacks     // 'JavaScript'

当我们访问developer对象中不存在的breathes属性时,就会去原型对象中查找,仿佛有一个神秘的链接指向原型对象。

developer.breathes;  // 'air'

在大多数浏览器中都是以__proto__属性作为这个神秘的链接

console.log(developer.__proto__ === monkey);  // true

在学习的过程中,我们可以使用这个链接,但是在实际的项目开发中不要使用它,因为并不是所有的浏览器都有__proto__属性。

我们可以使用Object.getPrototypeOf()代替它。

  先来谈一下类属性和实例属性

  图片 3

  类方法:是类对象所拥有的方法,需要用修饰器”@classmethod”来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以”cls”作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以’cls’作为第一个参数的名字,就最好用’cls’了),能够通过实例对象和类对象去访问。

class people:
    name = 'jack'       #定义了一个属性
    #定义了一个方法
    def printName(self):
        print self.name

  类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义:

 

class people:
    __name = 'jack'
    __age = 12

    def getName(self):
        return self.__name
    def getAge(self):
        return self.__age

p = people()
print p.getName(),p.getAge()

五.类属性、实例属性、类方法、实例方法以及静态方法

class people:
    country = 'china'

    #类方法,用classmethod来进行修饰
    @classmethod
    def getCountry(cls):
        return cls.country

p = people()
print p.getCountry()    #可以用过实例对象引用
print people.getCountry()    #可以通过类对象引用

  如果对self不好理解的话,可以把它当做C++中类里面的this指针一样理解,就是对象自身的意思,在用某个对象调用该方法时,就将该对象作为第一个参数传递给self。

  在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。

  这段程序运行会报错:

class className:
    block

  

  析构方法__del__(self)在释放对象时调用,支持重载,可以在里面进行一些释放资源的操作,不需要显示调用。

  在了解了类基本的东西之后,下面看一下python中这几个概念的区别。

  

  对于类属性和实例属性,如果在类方法中引用某个属性,该属性必定是类属性,而如果在实例方法中引用某个属性(不作更改),并且存在同名的类属性,此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性,若实例对象没有该名称的实例属性,则引用的是类属性;如果在实例方法更改某个属性,并且存在同名的类属性,此时若实例对象有该名称的实例属性,则修改的是实例属性,若实例对象没有该名称的实例属性,则会创建一个同名称的实例属性。想要修改类属性,如果在类外,可以通过类对象修改,如果在类里面,只有在类方法中进行修改。

  图片 4

  定义了一个people类,里面定义了name和age属性,默认值分别为’jack’和12。在定义了类之后,就可以用来产生实例化对象了,这句p
= people(
)实例化了一个对象p,然后就可以通过p来读取属性了。这里的name和age都是公有的,可以直接在类外通过对象名访问,如果想定义成私有的,则需在前面加2个下划线
‘ __’。

class people:
    country = 'china'


print people.country
p = people()
print p.country
p.country = 'japan' 
print p.country      #实例属性会屏蔽掉同名的类属性
print people.country
del p.country    #删除实例属性
print p.country

二.属性

  people类定义完成之后就产生了一个全局的类对象,可以通过类对象来访问类中的属性和方法了。当通过people.name(至于为什么可以直接这样访问属性后面再解释,这里只要理解类对象这个概念就行了)来访问时,people.name中的people称为类对象,这点和C++中的有所不同。当然还可以进行实例化操作,p=people(
),这样就产生了一个people的实例对象,此时也可以通过实例对象p来访问属性或者方法了(p.name).

  静态方法:需要通过修饰器”@staticmethod”来进行修饰,静态方法不需要多定义参数。

  比如 __cmp__( ), __len( )__等,具体的用法可以参考这篇博文:

class people:
    country = 'china'

    @staticmethod
    #静态方法
    def getCountry():
        return people.country


print people.getCountry()     

  在类中我们可以定义一些属性,比如:

  在上面代码中注释的很清楚了,name是一个属性,printName(
)是一个方法,与某个对象进行绑定的函数称作为方法。一般在类里面定义的函数与类对象或者实例对象绑定了,所以称作为方法;而在类外定义的函数一般没有同对象进行绑定,就称为函数。

一.如何定义一个类

                      Python 面向对象编程(一)

  图片 5

  理解了类、类对象和实例对象的区别之后,我们来了解一下Python中属性、方法和函数的区别。

class people:
    name = 'jack'

    #__init__()是内置的构造方法,在实例化对象时自动调用
    def __init__(self,age):
        self.age = age

p = people(12)
print p.name    #正确
print p.age     #正确

print people.name    #正确
print people.age     #错误

  

class people:
    __name = 'jack'
    __age = 12

p = people()
print p.__name,p.__age

  在类外对类对象people进行实例化之后,产生了一个实例对象p,然后p.age =
12这句给p添加了一个实例属性age,赋值为12。这个实例属性是实例对象p所特有的,注意,类对象people并不拥有它(所以不能通过类对象来访问这个age属性)。当然还可以在实例化对象的时候给age赋值。

  结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变。

  运行结果:

  如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。

  图片 6

class people:
    name = 'jack'  #公有的类属性
    __age = 12     #私有的类属性

p = people()

print p.name             #正确
print people.name        #正确
print p.__age            #错误,不能在类外通过实例对象访问私有的类属性
print people.__age       #错误,不能在类外通过类对象访问私有的类属性

  注意类名后面有个冒号,在block块里面就可以定义属性和方法了。当一个类定义完之后,就产生了一个类对象。类对象支持两种操作:引用和实例化。引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称作实例对象。比如定义了一个people类:

  还有其他的一些内置方法:

  构造方法__init__(self,….)在生成对象时调用,可以用来进行一些初始化操作,不需要显示去调用,系统会默认去执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。

三.方法

  实例方法:在类中最常定义的成员方法,它至少有一个参数并且必须以实例对象作为其第一个参数,一般以名为’self’的变量作为第一个参数(当然可以以其他名称的变量作为第一个参数)。在类外实例方法只能通过实例对象去调用,不能通过其他方式去调用。

class people:
    name = 'jack'
    age = 12

p = people()
print p.name,p.age

  在Python中有一些内置的方法,这些方法命名都有比较特殊的地方(其方法名以2个下划线开始然后以2个下划线结束)。类中最常用的就是构造方法和析构方法。

  从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。

  实例属性是不需要在类中显示定义的,比如:

四.类中内置的方法

  类方法还有一个用途就是可以对类属性进行修改:

class people:
    country = 'china'

    #实例方法
    def getCountry(self):
        return self.country


p = people()
print p.getCountry()         #正确,可以用过实例对象引用
print people.getCountry()    #错误,不能通过类对象引用实例方法
class people:
    country = 'china'

    #类方法,用classmethod来进行修饰
    @classmethod
    def getCountry(cls):
        return cls.country

    @classmethod
    def setCountry(cls,country):
        cls.country = country


p = people()
print p.getCountry()    #可以用过实例对象引用
print people.getCountry()    #可以通过类对象引用

p.setCountry('japan')   

print p.getCountry()   
print people.getCountry()