简体   繁体   中英

Is it possible to have an interface that has private / protected methods?

Is it possible in PHP 5 to have an interface that has private / protected methods?

Right now I have:

interface iService
{
    private method1();
}

That throws an error:

Parse error: syntax error, unexpected T_STRING, expecting T_VARIABLE

I just want to have confirmation that it is the case that an interface can only contain public methods.

The PHP manual page about interfaces explicitly states:

All methods declared in an interface must be public; this is the nature of an interface.

I guess this explains the error you are getting ;-)

Interfaces are used to describe public methods of a class implementing that interface. You can never have a private method in an interface. Any methods in an interface are assumed to be in use and should not be changed.

Interfaces is the PHP link, but this is standard in OO programming.

In general an interface can only have public members, because the only function of an interface is to be inherited.

From PHPfreaks.com tutorial:

PHP5 features interfaces. Not to be confused with interfaces in the more general sense, the interface keyword creates an entity that can be used to enforce a common interface upon classes without having to extend them like with abstract classes. Instead an interface is implemented.

Interfaces are different from abstract classes. For one, they're not actually classes. They don't define properties, and they don't define any behaviour. The methods declared in an interface must be declared in classes that implement it.

Because an interface in the more general sense is a definition of how an object interacts with other code, all methods must be declared public (see section on visibility in this chapter). Using abstract classes, an abstract method can have any visibility, but the extending classes must have their implementations use the same (or weaker) visibility. Implementing an interface adds the methods as abstract methods to the subject class, failure to implement it will result in an error like the following:

Fatal error: Class SomeConcreteClass contains n abstract method(s) and must therefore be declared abstract or implement the remaining methodsYes, abstract classes can implement interfaces.

interfaces are type declarations. a type is set of values, plus a set of operations that can be carried upon them from outside. a private method doesn't fit into this picture.

interface T {
  public /*int*/ function f(array $a);
}
interface U {
  public /*T*/ function g(T $t);
}

class C implements U {
    public function g(T $t) {
        ...
        $x = $t->f();
        ...
    }
}

interfaces are useful because they state, well, objects' interfaces. how the objects communicate with their environment.

now let's say T::f could be declared private. how would that be useful to other objects? it would not callable from outside, it would not be part of its interface.

In many cases, an interface definition helps other modules guarantee the behavior and the API of a class. In those cases, private methods are not something the other modules can access or understand. That's why you can never put private methods on an interface.

Big NO , any method in the Interface will never have private or protected access identifier.

**All methods declared in an interface must be public; this is the nature of an interface.

Few other interesting facts about interface

Interfaces can be extended like classes using the extends operator. They can extend only other interfaces. (source: https://www.php.net/manual/en/language.oop5.interfaces.php )

Note that it is possible to declare a constructor in an interface, which can be useful in some contexts, eg for use by factories. Signature should be same in the child class.

In your case, even another problem is - function keyword is missing in the function declaration. It should be

interface iService
{
    public function method1();
}

As stated, interfaces can only define the publicly visible methods. I wanted to show an example of how protected methods can be handled. To impose the use of specific protected methods, it is possible to create an abstract class that implements the interface.

This especially makes sense if the abstract class can already handle some of the workload, to simplify the actual implementation. Here for example, an abstract class takes care of instantiating the result object, which is always needed:

First off, the interface.

interface iService
{
   /**
    * The method expects an instance of ServiceResult to be returned.
    * @return ServiceResult
    */
    public function doSomething();
}

The abstract class then defines the internal methods structure:

abstract class AbstractService implements iService
{
    public function doSomething()
    {
        // prepare the result instance, so extending classes
        // do not have to do it manually themselves.
        $result = new ServiceResult();

        $this->process($result);

        return $result;
    }

   /**
    * Force all classes that extend this to implement
    * this method.
    *
    * @param ServiceResult $result
    */
    abstract protected function process($result);
}

The class that does the actual implementation automatically inherits the interface from the abstact class, and only needs to implement the protected method.

class ExampleService extends AbstractService
{
    protected function process($result)
    {
         $result->setSuccess('All done');
    }
}

This way the interface fulfills the public contract, and through the AbstractService class, the internal contract is fulfilled. The application only needs to enforce the use of the AbstractService class wherever applicable.

Книга "Java полное руководство - Герберт Шилдт

Закрытые методы интерфейсов С версии JDK 9, в интерфейс можно включать закрытый метод. Такой метод можно вызвать только из метода, реализуемого по умолчанию или другого закрытого метода в том же самом интерфейсе. А поскольку закрытый метод интерфейса объявляется как private, то им нельзя воспользоваться в коде за пределами того интерфейса, где он определен.

Главное преимущество закрытого метода интерфейса заключается в том, что он позволяет использовать общий фрагмент кода в двух и большем числе методов с реализацией по умолчанию, исключая тем самым дублирование кода.

В качестве примера ниже приведена очередная версия интерфейса IntStack с двумя реализуемыми по умолчанию методами popNElements() и skipAndPopNElements(). Первый из них возвращает массив из N элементов, начиная с вершины стека, а второй сначала пропускает указанное количество элементов, а затем возвращает массив из следующих N элементов. В обоих методах вызывается закрытый метод getElements() с целью извлечь из стека массив с указанным количеством элементов.

Обратите внимание на то, что закрытый метод getElements() вызывается в обоих методах popNElements() и skipAndPopNElements() с целью получить возвращаемый массив извлекаемых из стека элементов. Благодаря этому исключается дублирование одного и того же кода в этих реализуемых по умолчанию методах.

Следует, однако, иметь в виду, что метод getElements() нельзя вызвать за пределами его интерфейса, поскольку он объявлен закрытым. Это означает, что его применение ограничивается пределами интерфейса IntStack (в данном случае - методами с реализацией по умолчанию). А поскольку для извлечения элементов из стека в методе getElements() применяется метод рор(), то в нем автоматически вызывается вариант данного метода, предоставляемый в реализации интерфейса IntStack. Следовательно, метод пригоден для работы с классом любого стека, реализующим интерфейс IntStack.

//Очередная версия интерфейса IntStack с закрытым методом, применяемым в двух реализуемых по умолчанию методах. interface IntStack { void push(int item); // сохранить элемент в стеке int pop(); // извлечь элемент из стека

// Метод с реализацией по умолчанию, возвращающий массив из N элементов, начиная с вершины стека
default int[] popNElements(int n) {
    return getElements(n); // возвратить запрашиваемые элементы из стека
}

// Метод с реализацией по умолчанию, возвращающий из стека массив из N элементов,
// следующих после указанного количества пропускаемых элементов
default int[] skipAndPopNElements(int skip, int n) {
    getElements(skip);      // пропустить указанное количество элементов в стеке
    return getElements(n);  // возвратить запрашиваемые элементы из стека
}

// Закрытый метод, возвращающий массив из N элементов, начиная с вершины стека
private int[] getElements(int n) {
    int[] elements = new int[n];
    for (int i = 0; i < n; i++) elements[i] = pop();
    return elements;
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM