面向对象 - 抽象类

  • 作者:KK

  • 发表日期:2017.4.21


提示

在程序员前3年的实际编程中并不经常用到抽象类,但是你接触别人的代码偶尔会出现抽象类,所以在这里需要了解它是怎么一回事,以后可以回来复习以便解读别人的代码


定义一个空的抽象类

//定义抽象类,在class前面加个abstract就可以
abstract class User{}


//实例化抽象类
$user = new User();	//报错

就像平时定义一个类一样,在class前面加abstract就行

可是new的时候会报错,因为抽象类是无法被实例化的


可以被继承

abstract class User{}
class User2 extends User{} //继承抽象类User

$user2 = new User2(); //实例化成功

定义抽象方法

在抽象类里面,抽象方法是一个没有代码的方法:

abstract class User{
	abstract public function getName();
}

和平时在类里声明方法差不多,但在作用域修饰符(public | protected | private)前面加个abstract,另外函数最后不会有{ }这对花括号,而是在圆括号后面直接以;号结束


子类一定要实现抽象方法

以下代码会报错:

abstract class User{
	abstract public function getName();
}

class User2 extends User{} //代码运行到这里的时候就会报错

报错是因为User2这个类没有实现User的抽象方法,怎么实现呢?那就是定义这个方法:

abstract class User{
	abstract public function getName();
}

class User2 extends User{
	public function getName(){
		echo 123; //或者不写任何代码
	}
}

由此可见,抽象类可以逼着子类一定要定义这个方法;这种特性在软件架构上很常见,只是初级程序员比较少接触架构

比如说一个商城有商品类,那可以逼着子类一定要实现一个public function getPrice()方法来实现获取商品的价格(子类通常是代表了各种商品类型类)


抽象类可以有不抽象的东西

abstract class User{
	const AAA = 111; //可以定义常量

	public $name = ''; //可以定义属性
	
	protected $age = 11;
	
	private $type = 22;
	
	//定义一个普通的公共方法
	public function test1(){
		echo 'test1';
		$this->name = 'qqq';
	}
	
	//只有这个方法是抽象的
	abstract public function test2();
}


//继承User后只需要实现test2方法就行了
class User2 extends User{
	public function test2(){
		echo 'test2 by user2';
	}
}


//调用测试
$user2 = new User2();
echo $user2->age; //11
$user2->test1(); //test1
echo $user2->name; //qqq
$user2->test2(); //test2 by user2

可以调用抽象类的静态方法和属性等

即使不能new也可以调用静态的东西

abstract class User{
	const AAA = 'xxx';

	public static $name = 'Jay';

	public static function test(){
		echo '123';
	}
}


//调用测试
echo User::AAA; //xxx
echo User::$name; //Jay
User::test(); //123