面向对象面向对象基本面向对象什么是类?具有相同属性(特征)和方法(行为)的个体的集合,类是一个抽象概念。什么是对象?从类中获得的具有特定属性值的个体称为对象。对象是具体的个体。例如:人类;三类与对象的关系?类是对象的抽象!对象是类的具体化!类只表示这些对象有哪些属性,不能有具体的值,所以类是抽象的。类的所有属性都赋值后,对象就是一个具体的个体,所有的对象都是具体的。类的声明和实例化如何声明一个类:class类名{访问修饰符$property[=defaultvalue];[访问修饰符]functionmethod(){}}classSimpleClass{//属性声明public$var='默认值';//方法声明publicfunctiondisplayVar(){echo$this->var;}}声明类注意事项:类名只能由字母数字下划线组成,开头不能是数字,必须符合大驼峰规则;类名必须用class修饰,类名后不能有();属性必须有访问修饰符,方法不能有访问修饰符。实例化对象和对象属性方法的调用:$objectname=newclassname();//()可以在没有类的情况下调用属性和方法:$objectname->$attributename;//use->callattribute,属性名不能有$符号调用类内部的属性和方法:$this->$属性名;构造函数什么是构造函数?构造函数是类中的一个特殊函数。当我们使用new关键字实例化一个对象时,相当于调用类的构造函数。构造函数做什么?当一个对象被实例化时,会自动调用它为对象的属性赋初值!构造函数的写法:构造函数的名字必须和类的名字相同(废弃)[public]functionPerson($name){$this->name=$name;}使用魔术方法__construct[public]function__construct($name){$this->name=$name;}构造函数注意事项:第一种写法,构造函数名必须与类名相同!!!!如果一个类没有手写构造函数,系统默认会有一个空参构造,可以使用newPerson();如果我们写一个带参数的构造函数,就不会再有空参数构造,也就是不能直接使用newPerson();Person之后的()中的参数列表必须满足构造函数的要求!!!!如果两个构造函数都存在,则使用__construct。析构函数:__destruct():在对象被销毁释放前自动调用析构函数;析构函数不能有任何参数;析构函数常用于对象使用后释放资源、关闭资源等。魔术方法:在PHP中,我们提供了一系列以__开头的函数。这些函数不需要手动调用,而是会在合适的时候自动调用。这样的函数被称为magic,被称为magicfunctions。例如:函数__construct(){}当类的对象是新的时自动调用。函数__destruct(){}在对象被销毁时自动调用。我们要求,除了魔术方法,自定义函数和方法不能以__开头。最后,一般对于功能比较复杂的类,我们会单独写在一个class文件中。类文件以相同的小写命名,使用“类名小写.class.php”的方法。在其他文件中使用这个类时,可以使用include导入这个“.class.php”文件。封装与继承什么是封装?通过访问修饰符,将类中不需要外部访问的属性和方法私有化,实现访问控制。注意:实施访问控制,而不是拒绝访问。也就是说,我们将属性私有化后,需要提供相应的方法,让用户可以通过我们提供的方法来处理属性。包装的作用?用户只关心类能提供的功能,而不关心功能实现的细节!(封装方式)控制用户的数据,防止设置非法数据,控制返回给用户的数据(属性封装+set/get方式)实现封装操作?方法封装对于一些只在类内部使用,而不能在外部使用的方法,我们可以使用private来将此类方法私有化。privatefunctionformatName(){}//该方法只能在类内部使用$this调用functionshowName(){$this->formatName();}属性封装+set/get方法控制属性的设置和读取,可以将属性私有化,要求用户通过我们提供的set/get方法来设置private$age;//set方法functionsetAge($age){$this->age=$age;}//get方法函数getAge(){返回$this->age;}$object->getAge();$object->setAge(12);propertyencapsulation+magicmethod__get(->__set(,->=}$Object->age;//访问对象的私有属性时,会自动调用__get()magic方法,并将访问的属性名传递给__get()method;$object->age=12;//设置对象的私有属性,自动调用__set()魔术方法,并将设置的属性名和属性值传递给__set()方法;注意:在magic方法,可以通过分支结构判断$key的不同,进行不同的操作关于封装的magic方法:__set($key,$value):给类私有属性赋值时自动调用,并且在调用时传递两个参数给该方法:要设置的属性的名称,和属性的值。__get($key,$value):读取类的私有属性时自动调用。调用时,传递一个参数给方法,要读取的属性名;__isset($key):Automat当外部使用isset()函数检测私有属性时,会被调用。使用isset();检测默认不检测的私有属性。false因此,我们可以使用__isset();自动调用时返回内部检测结果的函数。function__isset($key){returnisset($this->$key);}当外部使用isset($objectname->privateattribute);检测,会自动调用上面__isset()返回的结果!__unset($key):当外部使用unset()函数删除私有属性时,自动调用;function__unset($key){unset($this->$key);}在unset($objectname->privateattribute)时在外部使用;删除属性时,属性名会自动传递给__unset(),由这个魔术方法处理。继承基础知识:继承是如何实现的?对子类使用extends关键字,使子类继承父类;classStudentextendsPerson{}继承注意事项?子类只能继承父类的非私有属性。子类继承父类后,相当于将父类的属性和方法复制到子类中,直接使用$this调用即可。PHP只能继承单继承,不支持一个类继承多个类。但是一个类有多层继承。classPerson{}classAdultextendsPerson{}classStudentextendsAdult{}//Student类同时具有Adult类和Person类的属性和方法方法重写(方法重写)子类继承父类子类重写父类已有的方法类满足以上两个条件,称为方法覆盖。重写后,子类调用方法,会调用子类自己的方法。同样的,除了方法重写之外,子类也可以有与父类同名的属性进行属性重写。如果子类重写了父类的方法,那么子类中如何调用父类的同名方法呢?Partent::方法名();因此,当子类继承父类时,子类构造的第一步就是调用父类构造进行复制。函数__construct($name,$sex,$school){partent::__construct($name,$sex);$this->school=$school;}PHP关键字final最终修饰类,该类为最终类,不可继承!final修改方法,该方法为final方法,不可重写!final不能修改属性。static可以修饰属性和方法,分别称为静态属性和静态方法,也称为类属性和类方法;静态属性和静态方法只能通过类名直接调用。使用“类名::$静态属性”、“类名::静态方法()”Person::$sex;人::说();静态属性和方法将在加载类时声明,然后再生成对象。在静态方法中,不能调用非静态属性或方法;在非静态方法中,可以调用静态属性和方法。(因为加载类时已经生成了静态属性和方法,此时还没有实例化非静态属性方法)在一个类中,可以使用self关键字来引用类名。人类{static$sex="nan";函数说(){echoself::$sex;}}静态属性是共享的,即许多新对象共享一个属性。const关键字:在类中声明常量,而不是define()函数!必须使用const关键字。和define()语句类似,const关键字声明的常量不带$并且必须全部大写!常量一旦声明,就不能再改变。调用的时候,和static一样,使用类名调用Person::constant。instanceof运算符:检查一个对象是否是某个类的实例。(包括父母,祖父母,曾祖父...)$zhangsaninstanceofPerson;【小结】几个特殊的算子:.只能连接字符串;"".""=>声明数组时,关联的key和Value["key"=>"value"]->object($thisnewobject)调用成员属性和成员方法;::使用parent关键字调用父类中的同名方法:parent::say();,使用类名(和self)调用类中的静态属性、静态方法和常量。魔术方法总结__construct():构造函数,新建对象时自动调用。__destruct():析构函数在对象被销毁之前自动调用。__get():访问类中的私有属性时自动调用。传递读取的属性名并返回$this->属性名__set():给类的私有属性赋值时自动调用。传递需要设置的属性名和属性值;__isset():当使用isset()检测对象的私有属性时,会自动调用。传入检测到的属性名并返回isset($this->属性名);__unset():当unset()用于删除对象的私有属性时,会自动调用。传入删除的属性名,执行unset($this->attributename);__toString():当使用echo打印对象时,会自动调用。返回打印对象时要显示的内容;返回必须是一个字符串;__call():调用类中未定义或未公开的方法时,会自动调用。传递被调用的函数名,以及一个参数列表数组;__clone():当使用clone关键字克隆对象时,会自动调用。作用是初始化新克隆的对象;__sleep():对象序列化时自动调用。返回一个数组,数组中的值是可以序列化的属性;__wakeup():对象反序列化时自动调用。为了反序列化新生成的对象,初始化赋值;__autoload():该函数需要在类外声明。实例化未声明的类时自动调用。传递实例化的类名,可以使用类名自动加载对应的类文件。抽象类和抽象方法什么是抽象方法?没有方法体{}的方法必须用abstract关键字修饰。这样的方法称为抽象方法。抽象函数说();//抽象方法什么是抽象类?用abstract关键字修饰的类是抽象类。AbstractclassPerson{}抽象类注意事项:抽象类可以包含非抽象方法;包含抽象方法的类一定是抽象类,抽象类不一定非要包含抽象方法;抽象类不能被实例化。(抽象类可能包含抽象方法,抽象方法没有方法体,实例化调用没有意义)我们使用抽象类的目的就是限制实例化!!!如果子类继承抽象类,那么子类必须重写父类的所有抽象方法,除非子类也是抽象类。使用抽象类的作用?限制实例化。(抽象类是一个不完整的类,里面的抽象方法没有方法体,所以不能实例化。)抽象类为子类的继承提供了规范。如果一个子类继承了一个抽象类,它必须包含并实现这个抽象类。定义抽象方法。接口和多态接口什么是接口?接口是一种规范,它提供了一组方法组合,这些方法组合必须由实现该接口的类来实现。使用interface关键字声明接口;接口Inter{}接口中的所有方法都必须是抽象方法。接口中的抽象方法不需要也不可以用abstract修饰。接口不能声明变量,不能有属性,只能使用常量!!!接口可以继承接口,使用extends关键字!接口使用extends继承接口,可以实现多重继承。interfaceint1extendsInter,Inter2{}类可以实现接口,使用implements关键字!类使用implements实现接口,可以同时实现多个接口,用逗号分隔;abstractclassPersonimplementsInter,Inter2{}一个类实现了一个或多个接口,那么这个类必须实现所有接口方法中的所有抽象!除非,这个类是一个抽象类。接口&&抽象类的区别在声明方式上,接口使用interface关键字,抽象类使用abstractclass。在实现/继承方面,类使用extends继承抽象类,使用implements实现接口。抽象类只能单继承,接口可以有多种实现方式。(interfaceextendsinterface),多实现(classimplementsinterface)抽象类可以有非抽象方法,接口只能有抽象方法,不能有抽象方法。抽象类中的抽象方法必须用abstract关键字修饰,接口中的抽象方法不能有修饰符。抽象类是可以具有属性和变量的类;接口只能有常量。多态性一个类被多个子类继承。如果这个类的一个方法在多个子类中表现出不同的功能,我们称这种行为为多态性。实现多态的必要途径:子类继承父类;子类重写父类方法;父类引用指向子类对象
