【web 开发】生活中大家都喜欢搞模板来规范化操作,抽象类却玩不明白-PHP的抽象类(63)

举报
迷彩 发表于 2023/07/24 10:34:36 2023/07/24
【摘要】 前言生活中大家都喜欢定标准搞模板来规范化一系列流程,抽象类和接口却玩不明白,抽象类和接口相似,都是一种比较特殊的类,抽象类是一种特殊的类,而接口也是一种特殊的抽象类。他们通常配合面向对象的多态性一起使用。虽然声明和使用都比较容易,但他们的作用在理解上会稍微困难一点,接下来本文就带你了解抽象类的相关内容及使用.什么是抽象类在OOP语言中,一个类可以有一个或多个子类,而每个类都至少有一个公有方法...

前言

生活中大家都喜欢定标准搞模板来规范化一系列流程,抽象类和接口却玩不明白,抽象类和接口相似,都是一种比较特殊的类,抽象类是一种特殊的类,而接口也是一种特殊的抽象类。他们通常配合面向对象的多态性一起使用。虽然声明和使用都比较容易,但他们的作用在理解上会稍微困难一点,接下来本文就带你了解抽象类的相关内容及使用.

什么是抽象类


在OOP语言中,一个类可以有一个或多个子类,而每个类都至少有一个公有方法作为外部代码访问他的接口。而抽象方法就是为了方便继承而引入的。接下来,先介绍一下抽象类和抽象方法的声明,然后说明其用途。在声明抽象类之前,我们先了解什么是抽象方法。抽象方法就是没有方法体的方法,所谓没有方法体是指在方法声明时没有花括号及其中的内容,而是在声明方法时直接在方法名后加上分号结束。另外,在声明抽象方法时,还要使用关键字abstract来修饰,声明抽象方法的格式如下代码所示:

abstract function funcName();  //后面是没有方法体的,也就是后面没有花括号以及里面的内容

声明抽象类的格式如下:

abstract class ClassName{
    //todo
    ....
}

抽象类中可以没有抽象方法,但只要在声明类时有一个方法是抽象方法,说明这个类就是抽象类,抽象类也要使用abstract关键字来修饰。在抽象类中可以有不是抽象的成员方法和成员属性,但访问权限不能使用private关键字来修饰,也就是不能声明为私有类,因为抽象类是不能被实例化的,即不能直接构造一个该类的对象。而且抽象类中的抽象方法需要被继承他的子类重写,并实现它。下面我们通过具体的例子来了解抽象类的声明及使用:

<?php
abstract class Person{
	protected $name;
	protected $country;
	
	function __construct($name='', $country='中国'){
		$this->name = $name;
		$this->country = $country;
	}
	
	//使用abstract修饰的方法为抽象方法,没有方法体 ,当多个类会用到一个或多个同样的方法,且个别方法有又些区别的时候,这时候就可以把有区别这个方法抽象出来,由子类去实现
	abstract function say(); 
	
	abstract function eat();
	
	function sport(){
		echo $this->name . '在运动...';
	}
}

上面代码声明了一个抽象类Person,在这个类中定义了两个成员属性:姓名,国家,一个构造方法,两个抽象方法,一个实体方法(非抽象方法).抽象类就像是一个"半成品"的类,在抽象类中有没有被实现的抽象方法,所以抽象方法是不能被实例化的,即无法直接使用抽象方法创建对象.既然抽象类是一个"半成品"的类,那么使用抽象类有什么作用呢?


使用抽象类就包含了继承关系,他是为他的子类定义公共接口,将它的操作(全部或者部分)交给子类去实现,就是将抽象类作为子类重载的模板使用,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守.当子类集成抽象类以后,就必须把抽象类中的抽象方法按照子类自己的需要去实现.且子类必须把父类中的抽象方法全部实现,否则子类中还存在抽象方法,所以还是抽象类,也不能进行实例化.下面我们继续通过例子来了解相关用法:

写一个子类来集成前面写的抽象类Person.

<?php
abstract class Person{
	protected $name;
	protected $country;
	
	function __construct($name='', $country='中国'){
		$this->name = $name;
		$this->country = $country;
	}
	
	//使用abstract修饰的方法为抽象方法,没有方法体 ,当多个类会用到一个或多个同样的方法,且个别方法有又些区别的时候,这时候就可以把有区别这个方法抽象出来,由子类去实现
	abstract function say(); 
	
	abstract function eat();
	
	function sport(){
		echo $this->name . '在运动...';
	}
}

//继承抽象类Person
class  ChineseMan extends Person{
	//重写父类Person的所有抽象方法
	function say(){
		echo $this->name . '来自' . $this->country . ',他说中文<br>';
	}
	
	function eat(){
		echo $this->name . '喜欢吃川菜<br>';
	}
}

//继承抽象类Person
class  American extends Person{
	//重写父类Person的所有抽象方法
	function say(){
		echo $this->name . '来自' . $this->country . ',他说英文<br>';
	}
	
	function eat(){
		echo $this->name . '喜欢吃火鸡<br>';
	}
}


$chineseman = new ChineseMan('张三', '中国');
$american = new American('Allen', 'USA');

$chineseman->say();
$chineseman->eat();

$american->say();
$american->eat();

执行结果如下:

总结

上面的例子中声明了两个类去继承抽象类Person,并将Person类中的抽象方法按各自的需求分别实现,这样两个子类就都可以创建对象了,抽象类Person就可以看成是一个模板,类中的抽象方法自己不去实现,只是规范了子类必须要有父类中声明的抽象方法,而且要按照自己类的特点实现抽象方法中的功能.举个不太恰当的例子:比如使用同一份图纸制造摩托车和自行车,它们都属于车这个大分类,他们都能在路上跑,都是两个轮子,但是他们产生动力的方式不一样,摩托车使用发动机驱动,而自行车需要脚蹬才能跑,在生产自行车和摩托车的时候,外形可以一样,但需要独立设计他们的动力系统,所以在设计图纸的时候我们就可以把动力这部分抽象出来,单独实现.也就是功能必须要有,但是具体实现各有不同.

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。