Jump to content

Interfaces and abstract functions


nloding

Recommended Posts

I decided to put this in a new topic ... here's the issue I've come across, and I've not tested the code so I'm not sure what it'll do ... figured I'd ask while I was coding, since the last topic of factories brought some good conversation.

 

You create a parent class that implements an interface.  Then you create a child class that extends the parent.  Does the child class need the functions the interface dictates?  I assume no, since the parent already has them and the 'implements' keyword isn't used in the child line.  But, by definition "When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child" and by definition, all methods in an interface are abstract ...

 

I still think the child class doesn't need them.  Am I right?  Here's the code example of what I'm asking:

 

<?php
interface myInterface {
function duh($wee);
function oops($uhoh);
}

class FakeClass implements myInterface {
public function duh($wee) {
  // ...
}
public function oops($uhoh) {
  // ...
}
}

class FakeKid extends FakeClass {
public function notFromInterface($canIDoThis) {
  // ...
}
private function alsoNotInTheInterface($isItPossible) {
  // ????????
}
// but there are no other functions from the interface here!
}

Link to comment
Share on other sites

That's perfectly acceptable, since FakeKid extends FakeClass (which Implements myInterface) , FakeKid has really defined the 2 functions which myInterface is expecting.

 

The only caveat is, though, since you have not declared FakeClass functions protected they CAN be overwritten by child objects.

Link to comment
Share on other sites

LONG post ahead!

 

Here is why I started this thread -- to make sure I could extend the database class how I wanted.  I'm trying to abstract as much code as I can ...

 

<?php
/**
* database_v2.inc
* 
* Making greater strides towards understanding design patterns and OOP
* encapsulation.  I'm trying very, very hard to get a strong set of db
* objects that can used in a factory pattern; this is forced practice
* to better understand all the principals involved.
* 
* The point of this exercise is to design a database class that abstracts
* as much of it's code as possible into child classes.
*/

// The interface (i.e., the design of the parent object)
interface dbInterface {
function connect($host, $user, $pass, $dbname);
function query($query);
function insert($table, $items, $values);
function update($table, $to_update, $where);
function execute($query);
function fetchAssoc($result);
function fetchArray($result);
function fetchObject($result);
function disconnect();
}

class dbParent implements dbInterface {
private $conn;
private $lastResult;
private $numQueries;

protected function __construct() {
	$this->lastResult = NULL;
}

protected function connect($host, $user, $pass, $dbname) {
	$this->conn = new mysqli($host, $user, $pass, $dbname);
}

protected function query($query) {
	$this->lastResult = $this->conn->query($query);
	$this->numQueries++;
}

protected function insert($table, $items, $values) {
	$query = "INSERT INTO " . $table . " " . $items . " VALUES " . $values;
	$this->conn->query($query);
	$this->numQueries++;
}

protected function update($table, $to_update, $where) {
	$query = "UPDATE " . $table . " SET " . $to_update . " WHERE " . $where;
	$this->conn->query($query);
	$this->numQueries++;
}

protected function execute($query) {
	$this->conn->query($query);
	$this->numQueries++;
}

protected function fetchAssoc($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_assoc();
	}
}

protected function fetchArray($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_array();
	}
}

protected function fetchObject($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_object();
	}
}

protected function disconnect() {
	$this->conn->close();
}
}

class dbUser extends dbParent {
// User related database functions, such as active users or registering
}

class dbSecurity extends dbParent {
// Security related database functions, such as comparing user/pass
}

class dbForum extends dbParent  {
// Forum related database functions, such as posting and viewing threads
}

 

All this generated by a factory, with a variable that defines what is called.  I'm not gonna paste it here, but basically you call Factory::getInstance('Security') and it calls 'dbSecurity' by doing "db" . $type;

 

That's where I'm headed with this whole thing ... I hope it works, I like the way it sounds in my head.

Link to comment
Share on other sites

Yeah, they'd have to public.  That's the point of a database class ... to provide a wrapper for the database functions for other functions, methods, classes, objects, dogs, cats, and programmers to use.  Besides, all methods declared in the interface must be public ...

Link to comment
Share on other sites

LONG post ahead!

 

Here is why I started this thread -- to make sure I could extend the database class how I wanted.  I'm trying to abstract as much code as I can ...

 

<?php
/**
* database_v2.inc
* 
* Making greater strides towards understanding design patterns and OOP
* encapsulation.  I'm trying very, very hard to get a strong set of db
* objects that can used in a factory pattern; this is forced practice
* to better understand all the principals involved.
* 
* The point of this exercise is to design a database class that abstracts
* as much of it's code as possible into child classes.
*/

// The interface (i.e., the design of the parent object)
interface dbInterface {
function connect($host, $user, $pass, $dbname);
function query($query);
function insert($table, $items, $values);
function update($table, $to_update, $where);
function execute($query);
function fetchAssoc($result);
function fetchArray($result);
function fetchObject($result);
function disconnect();
}

class dbParent implements dbInterface {
private $conn;
private $lastResult;
private $numQueries;

protected function __construct() {
	$this->lastResult = NULL;
}

protected function connect($host, $user, $pass, $dbname) {
	$this->conn = new mysqli($host, $user, $pass, $dbname);
}

protected function query($query) {
	$this->lastResult = $this->conn->query($query);
	$this->numQueries++;
}

protected function insert($table, $items, $values) {
	$query = "INSERT INTO " . $table . " " . $items . " VALUES " . $values;
	$this->conn->query($query);
	$this->numQueries++;
}

protected function update($table, $to_update, $where) {
	$query = "UPDATE " . $table . " SET " . $to_update . " WHERE " . $where;
	$this->conn->query($query);
	$this->numQueries++;
}

protected function execute($query) {
	$this->conn->query($query);
	$this->numQueries++;
}

protected function fetchAssoc($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_assoc();
	}
}

protected function fetchArray($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_array();
	}
}

protected function fetchObject($result = NULL) {
	if($result == NULL) $result = $this->lastResult;

	if($result == NULL || $result->num_rows < 1) {
		return NULL;
	} else {
		return $result->fetch_object();
	}
}

protected function disconnect() {
	$this->conn->close();
}
}

class dbUser extends dbParent {
// User related database functions, such as active users or registering
}

class dbSecurity extends dbParent {
// Security related database functions, such as comparing user/pass
}

class dbForum extends dbParent  {
// Forum related database functions, such as posting and viewing threads
}

 

All this generated by a factory, with a variable that defines what is called.  I'm not gonna paste it here, but basically you call Factory::getInstance('Security') and it calls 'dbSecurity' by doing "db" . $type;

 

That's where I'm headed with this whole thing ... I hope it works, I like the way it sounds in my head.

 

If I may butt in...

 

Why is there a dbInterface? May I suggest the following alternative:

 

<?php
abstract class DbAbstract {

protected $conn;
protected $lastResult;
protected $numQueries;

public function __construct($host, $user, $pass, $dbname) {
	$this->connect($host, $user, $pass, $dbname);
}
public function query($string){
	$this->lastResult = $this->doQuery($string);
	$this->numQueries++;
}	
public function insert($table, $items, $values) {
	$this->doInsert($table, $items, $values);
	$this->numQueries++;
}
abstract function doQuery($string);
abstract function doInsert($table, $items, $values);	
abstract function connect($host, $user, $pass, $dbname);
}

class DbMySQLi extends DbAbstract {

public function connect($host, $user, $pass, $dbname) {
	$this->conn = new mysqli($host, $user, $pass, $dbname);
}
public function doQuery($query) {
	return $this->conn->query($query);
}
public function doInsert($table, $items, $values) {
	$query = "INSERT INTO " . $table . " " . $items . " VALUES " . $values;
	$this->conn->query($query);
}
}
abstract class DAO {

protected $dbObject;

public static function factory($rdbms, $domain, $host, $user, $pass, $dbname){
	$daoClass = $domain.'DAO';
	$dbClass = 'Db'.$rdbms;
	return new $daoClass(new $dbClass($host, $user, $pass, $dbname));
}
}
class UserDAO extends DAO {

public function __construct(DbAbstract $dbObject){
	$this->dbObject = $dbObject;
}
public function getActiveUserCount(){
	$this->dbObject->query('SELECT count(id) FROM users WHERE active = "1"');
	//etc...
	return $count;
}
}
$userDao = DAO::factory('MySQLi', 'User', 'localhost', 'root', '', 'cms');
echo 'Active users: '.$userDao->getActiveUserCount();
?>

 

Look into Layer Supertype [PoEAA: 475].

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.