面向对象的类访问和对象访问的区别【this以及类访问】、静态成员的访问区别、类常量等、继承和重写、访问修饰限定符、冒泡排序

1.mysql封装类

在构造函数中定义初始化数据库连接的相关参数【因为实例化对象时传入的参数是该对象的唯一参数入口】
但是不需要再构造函数中进行冗余定义,而是在构造函数中进行调用类中的其他方法的方式来实现构造函数的设置工作【这样的模块分离使逻辑更加简单】

【重点】
2.静态成员
相当于每次实例化对象之间是有关系的【例如计数功能】
因为每次实例化类时创建的对象占用的空间都是新创建的,这一点需要注意,所以同一个类下的对象之间的变量并没有交互的效果。
【回想起当初函数中的静态局部变量的使用】
【延生到静态全局变量(并没有这个概念)的使用,也就是对象中的静态属性】
所以我们需要一个对象之间共有的数据【静态的属性】【这一点也就是单例的实现的依据,保证了数据库连接的单一实例对象】

【类的静态成员:被所有实例该类的对象所共享的成员,就是类的静态成员。实现原理是,只有静态成员才会被保存在类中进行标记,也只有这样才能保证对象之间共享的原理】
【需要使用static关键字进行声明】
【那么静态的方法有什么使用场景?静态方法相当于是对该方法调用次数的统计,也就是单例的实现需要静态方法】

【这是访问控制符】
【::】静态访问符【类名::成员名】【类访问符(因为该成员保存在类中,这样才能保证控制实例该类之间对象的共享数据)】【也叫范围解析操作符】
【—>】对象访问符【因为需要(对象名->成员名)来实现访问】

【关键字】
$this【在类中指代实例该类的对象。所以只能使用对象访问控制符。也是只能在类中使用】
self【在类中表当前类,只能用类访问控制符。(只能在类中使用)】
parent【这个也只能指代父类。也只能使用类访问控制符】
【也要注意类外访问该对象或类的访问控制,就得使用类名或对象名】

对访问控制符和关键字有一个清晰的认识【是因为指代和适用的情景不一致才会有这样区别的需要,不需要死记,很好理解】

【重点,this的出现在方法中的使用,以及区别静态方法与非静态的原理上的区别】
3.静态的使用问题
静态成员只能使用静态访问符来访问。

但是唯一例外的是php支持:对象名::静态成员【针对的就是访问静态成员。因为对象已经实例了该值,所以该对象也能找到对应的类操作也是可以的】
类名::非静态方法名;【也能正常执行,但是会报错】
例如:
<?php

class Student {
public $name = 'itcast';
public static $count = 10;

public function non_static_func() {
var_dump($this);//这个是进行区别静态与非静态方法的区别
echo '非静态方法<br>';
}
public static function static_func() {
var_dump($this);
echo '静态方法<br>';
}
}
$o = new Student;
$o->non_static_func();
$o->static_func();//

Student::static_func();//
Student::non_static_func();//
//四种情况,都能正常被访问
【原因是:方法本身就是一个可执行代码的集合,这也就是为什么方法即使是静态的,也能正常被执行,也是一致的。所以在php机制中,方法本身在类中就相当于是静态的,将该方法注册在可执行代码区,每一个对象都指向该方法(那么就相当于静态方法)】
就这一点区别
【那么对静态方法的区别是:在静态方法中使用$this一定不可用。$this只有实例化对象并且使用对象调用非静态方法时才能使用this指代当前对象】

【不过尽量不适用该情况】

在正常编程下,我们还是使用对象来访问非静态成员,使用类来访问静态成员【这样对各自的访问符也容易区别】
【在业务逻辑层面上才能区别是否是静态的方法:该方法如果是某些实例对象的,那么该方法使用非静态方法。如果该方法适用所有的对象,那么将该方法设置为静态方法。】
【虽然非静态方法也是对象引用到编码区进行执行,但是该方法中$this可以进行指定该对象进行操作,而不是使用类。所以使用该方法可以体现某些对象的特殊性】

【注意区别】

4.类常量
const关键字
在类内定义,属于类【区别于define,define可以在任何位置定义,在任何位置使用(只要define执行)】

类常量不需要使用访问修饰限定符(public之类的关键字)来访问【而是只要类能被访问,该常量就能使用】
访问时和静态属性一致【类::常量名】【只是不需要$访问,因为$是区别变量和常量的依据】


【总结:重点】
类中只有五种成员:
属性
方法
静态属性
静态方法
类常量

在类中直接使用echo之类的语法,会直接报错(包括在类中使用赋值等语句也是会出错)。只能将这些语句封装入相应的方法中才能使用。

【重点】
5.继承
如果一个对象使用另一个对象中的成员,就称作一个继承。【虽然是在类的层面上实现继承,但是实质上还是对象的成员对其进行继承】

extends关键字【在实例的过程中,会将继承的成员继承该对象】


原理:
面向对象中的概念都在对象上,只是在语法上,需要类进行实现这些概念。

出现的意义就是面向对象的代码重用。

继承子类和继承父类是多对一的关系【但是不可能子类继承多个父类的情况出现。也就是php本身并没有多继承的概念】
【实例出的对象也是继承父类的实例instanceof来判断对象对类的实例控制】

所以从对象层面来考虑继承,只是语法实现是在类的层面。这样就简单的多。


6.重写【继承后的成员的重新定义和parent关键字问题】
继承后的成员因为同名会被重新定义的行为就是重写。【但是其实并不是重写,而是类似于js的继承链的关系,一层层的查找该名字的属性是否出现,如果出现,即显示该值】
【这样的查找机制才是限制对象的属性的值的确定的一层层细化的原理。也能保证子类的修改对父类无影响】

parent用来指代继承父类【也是用在继承中,为了重写之余也能更*的调用继承的父类的成员】
【需要使用类访问符。用来访问父类的方法(这些方法一定是已经被子类的同名方法重写过,否则不需要使用parent进行访问)】

7.$this的确定
因为继承的parent的调用情形存在,相当于就是类对继承父类中的方法的调用
【该方法中是有可能出现$this关键字情形。这也就是类调用方法时,使用了this的情形】
【与之前说的只有对象调用非静态方法时的$this才能正常访问的情形有问题】

$this的获得
(1)哪个对象调用方法,方法内的$this指代的就是那个对象
(2)对象环境是可以向下传递的!【就是针对继承的情况】【只要子类的对象已经确定,那么在子类中的方法确定对象环境,则在该方法内,出现静态调用非静态方法,则会将该对象环境传递到该非静态方法中。此时的$this就是该子类的对象(虽然$this定义在父类中的非静态方法,而且是被子类调用)】


所以对于$this的关键就只有两点【真实对象调用,或者向下传递(子类中进行调用父类非静态方法时的对象指定的就是$this。但是静态调用非静态方法不需要一定发生在继承的场景中)】
例子:
<?php
class A {
public function in_a() {//这里尽量使in_a方法改为静态方法
var_dump($this);
}
}


class B {
public function in_b() {
var_dump($this);
echo '<br>';
A::in_a();//此时调用时,在A类中的指定方法下$this指的就是$o对象【但是现实使用这种调用情况不多】
}
}

$o = new B;
$o->in_b();

?>

$this的确定只有两点,第二点尤其重要【向下传递的特性,但是现实构造类的时候,尽量回避这种情况(静态调用非静态方法)。如果一定要调用,将该非静态方法构造为静态方法。防止$this的错乱】


8.访问修饰限定符
public共有的
protected保护的【本类和子类能够访问】
private私有的


php使用类的概念进行成员的访问限制。【对象和类进行区别】
在三个范围内进行限制
类内
类外
继承链上的类内【js也有继承链】
以上三个范围就包括一切访问范围。


判断成员在哪里定义、哪里访问来确定访问限制。【代码在哪里,绝对不是指某对象实例类就能表示在该类内访问。而是在对象中访问,叫在类外访问】
例子:
<?php
class A {
public function in_a_func() {
var_dump($this->property);//在A类中,在父类中(继承链)访问
}
}
class B extends A {
//成员定义在B类!
// public $property = 'public property<br>';
// protected $property = 'protected property<br>';
private $property = 'private property<br>';
public function in_b_func() {
var_dump($this->property);//在B类中访问,在本类内访问
}
}
class C extends B {
public function in_c_func() {
var_dump($this->property);//在C类内访问,在子类(继承链)*问
}
}
$c = new C;
var_dump($c->property);//在类外访问private
$c->in_c_func();//在继承链上的子类内访问private $property
$c->in_b_func();//在本类内访问private $property
$c->in_a_func();//在继承链上的父类内访问private $property


//var_dump($c->property);//在类外访问protected
//$c->in_c_func();//在继承链上的子类内访问protected $property
//$c->in_b_func();//在本类内访问protected $property
//$c->in_a_func();//在继承链上的父类内访问protected $property

//var_dump($c->property);//在类外访问public
//$c->in_c_func();//在继承链上的子类内访问public $property
//$c->in_b_func();//在本类内访问public $property
//$c->in_a_func();//在继承链上的父类内访问public $property


以上就是对访问位置和限制的所有区别
【其实关键也是方法的访问位置和方法内的属性的访问位置是不同的,也就是就算类外(对象)进行类内的方法访问,只要类内的方法中有对属性的访问,那么这种访问就是类内访问】
【重点。对访问位置和限制的问题的理解,其实也就是对象和类的代码位置的区别,将访问限制完全搞定】


【重点】
这样的访问修饰限制符的作用就是通过对访问的限制,实现对模块的封装,仅仅开放接口【接口可以别的访问,但是能够隐藏内部的实现】
将不需要外部使用的属性、方法进行私有或者保护,而仅仅留下接口进行public访问即可

9.访问修饰限定符的问题

访问修饰限制符的划定范围的主要问题就是:
在定义和访问的代码的位置决定是类内、继承链、类外
【即使类继承了另一个类,该属性也在子类对象出现,但是该属性的访问是属于继承链上。因为访问修饰限定符的作用是类的概念,继承本身是对象之间实现,并不影响访问修饰的范围】


注意:
(1)重写中,需要注意访问的是哪里定义的【因为存在继承链的问题,所以重写的成员才是优先被访问的成员,该权限的限制才是要注意的】
(2)私有成员的重写问题【私有成员不能被重写】【】

例:
<?php
class B {
//成员定义在B类!
public $public_p = 'in B public';
protected $protected_p = 'in B protected';
private $property = 'in B public property<br>';
public function in_b_func() {
var_dump($this->property);//在B类中访问,在本类内访问
}
}
class C extends B {
public $public_p = 'in C public';
protected $protected_p = 'in C protected';
private $property = 'in C public property<br>';
public function in_c_func() {
var_dump($this->property);//在C类内访问,在子类(继承链)*问
}
}
$o = new C;
var_dumP($o);//这样返回的对象中包含四个属性【其中有两个private的属性】【私有属性不能被重写】

echo '<hr>';
//$o->in_c_func();
//$o->in_b_func();//此时访问出的值与上一个不同

【重点】
在处理私有属性时,一定要确定私有属性的定义位置【因为该私有属性并不会被重写】

如果类需要通过继承,就不使用private关键字进行限制访问。【这样就回避了访问结果不一致的问题】

(3)对继承的成员进行重写,并且修改其访问修饰限定符【继承子类的限定符权限不能比父类的权限低】
【否则会报错】

例:
<?php


class A {
protected function f1() {
echo 'in A f1';
}
}
class B extends A {
public function f1() {
echo 'in B f1';
}
}


class C {
var $name;
function f1() {
}
}

class d {
public $name;
public function f1() {
}
}

10.冒泡排序
相邻的两个数进行比较,然后进行指定排序【升序的话,向后排】
冒泡排序的原理就是每一轮比较出来的数能够获取一个最大值【或最小值】
每轮需要比剩下的元素进行比较

总共有n个元素
1轮 需要比较n-1个比较
2轮 n-2
...
n-1 1
总共的比较次数为
(n-1)+(n-2)+...+1
就是每轮选出一个数来进行放置到指定的最后位置,再对剩下的元素进行比较
<?php
$array = array();//要进行冒泡排序的数组
for($i=0;$i<count($array);$i++){
for($j=0;$j<(count($array)-$i);$j++){
if($array[$j]>$array[$j+1]){
$a = $array[$j];
$array[$j] = $array[$j+1];
$array[$j+1] = $a;
}
}
}
?>
以上便实现了冒泡排序

【问题】
【今天需要进行一整套总结】
需要对访问修饰限制,继承,重写,关键字,以及访问符【类和对象】的关系进行总结
【访问限制和继承和重写的关系需要注意,也要对继承子类和父类之间的关系】