Страницы

Поиск по вопросам

Показаны сообщения с ярлыком интерфейс. Показать все сообщения
Показаны сообщения с ярлыком интерфейс. Показать все сообщения

понедельник, 30 марта 2020 г.

Почему в php рефлексия показывает что интерфейс это абстрактный класс?

#php #интерфейс #рефлексия #php5


Можете, пожалуйста, подсказать почему в php 5.6.30 данный код:

interface IInterface {
  public function someMethod();
  public function anotherMethod();
}
function classData( ReflectionClass $class )
{
    $details = "";
    $name = $class->getName();

    if ( $class->isInterface() ) {
        $details .= "$name -- это интерфейс
"; } if ( $class->isAbstract() ) { $details .= "$name -- это абстрактный класс
"; } return $details; } $class_info = new ReflectionClass('IInterface'); echo classData($class_info); выводит следующий результат: IInterface -- это интерфейс IInterface -- это абстрактный класс Т.е. почему интерфейс определяется как абстрактный класс? Если удалить методы из интерфейса, то отобразится: IInterface -- это интерфейс Интересный факт: hhvm лишён этого недостатка


Ответы

Ответ 1



Существует 2 типа «абстрактности» в php: explicit - класс, явно определённый, как abstract. implicit - класс/интерфейс, содержащий абстрактные методы. Проверить на explicit абстрактность можно так: if ($class->getModifiers() & ReflectionClass::IS_EXPLICIT_ABSTRACT) { // Перед нами абстрактный класс } Демонстрация

воскресенье, 8 марта 2020 г.

Имплементация интерфейса с generic type

#java #generics #интерфейс


Помогите с реализацией интерфейса. Допустим у нас есть интерфейс 

public interface Sorter> {
    void sort(List list);
}


и я хочу создать класс, который будет реализовывать этот интерфейс используя genec
types. Я пробовала так:

public class SorterImpl> implements Sorter {
    public void sort(List list){
        boolean erijuht1 = true; 
        boolean erijuht2 = true; 
        for(int a=0; a list.get(a+1)){
                erijuht1 = false;
            }
            if(list.get(a) < list.get(a+1)){ 
                erijuht2 = false;
            }
        }
    }
}


Проблема в том, что последний класс не хочет сравнивать объекты между собой.
Как мне реализовать данный интерфейс так, что бы класс был и с generic type, и мог
сравнивать объекты?
    


Ответы

Ответ 1



Вы не можете в данной функции сравнивать два объекта таким образом, так как не понятно какой из них считать большим, а какой меньшим (и равным). list.get() возвращает Вам объект класса T, наследуемый от Comparable. Значит мы можем использовать вызывать все методы этого класса, а в данном случае compareTo (возвращает 1,0 или -1). Осталось добавить код для перемены мест в случае если "больший" имеет меньший индекс. Вот что получилось: public class SorterImpl> implements Sorter { public void sort(List list) { // boolean erijuht1 = true; // boolean erijuht2 = true; for (int j = 0; j < list.size() - 1; j++) for (int a = 0; a < list.size() - j - 1; a++) { if (list.get(a).compareTo(list.get(a + 1)) > 0) { // erijuht1 = false; } else { // erijuht2 = false; T temp = list.get(a + 1); list.set(a + 1, list.get(a)); list.set(a, temp); } } } //Тестируем public static void main(String[] args) { List ar = new ArrayList() { { add(2); add(3); add(5); add(8); add(2); } }; SorterImpl s = new SorterImpl(); s.sort(ar); for (int i = 0; i < ar.size(); i++) { System.out.print(ar.get(i).toString() + " "); } } } Результат: 8 5 3 2 2

Нужно ли разделять интерфейсы и абстрактные классы в С++

#cpp #ооп #интерфейс


Как известно, отдельных языковых средств для объявления интерфейсов в С++, а их роль
могут выполнять абстрактные классы.
Но с идеологической точки зрения интерфейсы и абстрактные классы являются довольно
разными сущностями. Интерфейсы описывают некий контракт того, как можно взаимодействовать
с классом. Абстрактные классы являются корнем иерархии классов, используются для полиморфизма
в духе 

AbstractSuperClass* a = new SubClass;


и могут просто реализовывать общий функционал. 

Нужно ли, программируя на С++, разделять эти понятия и писать интерфейсы, как в Java/C#?
Или можно(нужно?) смешивать и использовать только абстрактные классы?  
    


Ответы

Ответ 1



В C#/Java нет множественного наследования классов, но есть множественное наследование интерфейсов. Поэтому в этих языках разделять интерфейсы и абстрактные классы приходится волей-неволей. В С++ такого ограничения нет, поэтому нет особой надобности в выделении отдельного понятия "интерфейс", и отделения его от абстрактного класса. Интерфейсом может служить любой абстрактный класс, ему даже не обязательно иметь публичных виртуальных функций (ну, кроме деструктора, если нужно полиморфное удаление). Пример такого интерфейса - паттерн NVI. При желании более соответствовать ООП парадигме языков C#/Java можно давать интерфейсным классам имена, начинающиеся с буквы I, или даже добавить #define interface struct чтобы выделить интерфейсный класс при объявлении/определении. Такие подходы используются в MS COM. Но в общем случае, этого не требуется, а проблему ромбовидной иерархии можно решить через виртуальное наследование.

среда, 4 марта 2020 г.

C# интерфейсы и абстрактные классы

#c_sharp #классы #наследование #интерфейс


Доброго!

Есть интерфейс IInterface,

Есть абстрактный класс его реализующий AClass

И есть абстрактный класс 

AClasses
{
  List Elements;

  void SomeMethod()
  {
    T _el = new T();
    _el.Some();
    Elements.Add(_el);
  }
}


Вот в методе SomeMethod() проблема так как это сделать нельзя. T должен наследоваться
от IInterface ну или на крайний случай от AClass. 

Так вот вопрос. Как заполнить List Elements в абстрактном классе
    


Ответы

Ответ 1



Например, при помощи ограничений на T: class AClasses where T : IInterface, new() { ... Это будет работать, если у ваших классов есть пустой конструктор. Если пустого конструктора нет, то создание экземпляров нужно делать как-нибудь по-другому, например, через фабрику или создающий делегат.

пятница, 28 февраля 2020 г.

Почему java воспринмает интерфейс comparator как функциональный

#java #интерфейс #lambda #лямбда_выражение


Недавно ознакомился с лямбда-выражениями и узнал, что с их помощью можно реализовать
Comparator. Но мне не даёт покоя то, что в этом интерфейсе объявлено два не статических
и не реализованных по умолчанию метода: compare() и equals(). И несмотря на это, интерфейс
считается функциональным, и метод compare() может быть реализован с помощью лябда-выражений. 

Как так? Почему метод equals() не воспринимается?
    


Ответы

Ответ 1



Интерфейс Comparator функциональный, потому что equals() - относится к public-методу класcа Object. Интерфейсы объявляют абстрактные методы относящиеся к public методам Object, но обычно делают это неявным образом и эти методы не учитываются.

четверг, 27 февраля 2020 г.

Что в Java является константой, а что - нет?

#java #переменные #интерфейс #константа


До недавнего времени я был почти на 100% убеждён в том, что прекрасно понимаю сущность
констант в языке программирования Java. Так было, пока я не наткнулся на один из примеров,
который был представлен в JLS (Java Language Specification). Он немного поверг меня
в ступор, и я не могу разобраться с этим вопросом вплоть до текущего момента.

Наверное, я не сильно ошибусь, если скажу, что типичных констант в языке программирования
Java нет вообще (во всяком случае, если смотреть с колокольни какого-нибудь С++). Даже
ключевое слово const, которое зарезервировано с незапамятных времён, но до сих пор
не используется, как бы ненавязчиво намекает нам об этом (не уверен, но вроде бы это
было сделано для того, чтобы сохранить обратную совместимость с С++ в том случае, если
константы всё-таки будут введены в язык).

В качестве некоторого общепринятого суррогата используется связка модификаторов static
final в процессе декларирования переменной. Если я правильно понимаю, то именно такие
переменные и считаются константами с точки зрения программистского сообщества ЯП Java.
В то же время, если заглянуть на просторах JLS в параграф, который посвящён инициализации
классов и интерфейсов, мы можем наткнуться на один интересный момент. Небольшая выдержка
оттуда:


  Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces


interface I {
    int i = 1, ii = Test.out("ii", 2);
}
interface J extends I {
    int j = Test.out("j", 3), jj = Test.out("jj", 4);
}
interface K extends J {
    int k = Test.out("k", 5);
}
class Test {
    public static void main(String[] args) {
        System.out.println(J.i);
        System.out.println(K.j);
    }
    static int out(String s, int i) {
        System.out.println(s + "=" + i);
        return i;
    }
}



  This program produces the output:
  
  1
  j=3
  jj=4
  3 
  
  The reference to J.i is to a field that is a constant
  variable (§4.12.4); therefore, it does not cause I to be initialized
  (§13.4.9).
  
  The reference to K.j is a reference to a field actually declared in
  interface J that is not a constant variable; this causes
  initialization of the fields of interface J, but not those of its
  superinterface I, nor those of interface K.
  
  Despite the fact that the name K is used to refer to field j of
  interface J, interface K is not initialized.


И вот этот момент мне совершенно непонятен! В интерфейсах все поля неявным образом
помечаются как public static final (другими они и не могут быть), что мы и видим в
приведённом примере. Все поля имеют совершенно одинаковый набор модификаторов, но при
этом, поле J.i называют константной переменной, а K.j константой уже не является, если
верить примеру, который приведён в JLS.

Что же такое константа с точки зрения JLS? Неужели это не абсолютно все статические
финализированные поля? Правильно ли я понял, что при присваивании значения через его
возврат функцией, мы уже не можем считать поле константой?
    


Ответы

Ответ 1



С точки зрения JLS: A constant variable is a final variable of primitive type or type String that is initialized with a constant expression То есть константа - это final переменная (причем речь не только о static и не только о полях) примитивного типа или типа String, которая проинициализирована константным выражением Вызов метода константным выражением не является, поэтому K.j - это не константа

четверг, 13 февраля 2020 г.

Вернуть реализующийся интерфейс IEnumerable<T> через метод, C#

#c_sharp #ссылки #интерфейс #методы


Добрый день, очень сильно плаваю в теме про обобщенные интерфейсы, методы. Был бы
весьма благодарен за подсказку, либо за ссылки, в каком направлении следует копать,
читать. Теорию прочитал с сайта professorweb.ru про интерфейсы, обобщение. Теория теорией,
что то понял, чего то нет, но на практике все равно не могу реализовать следующую задачку.

К примеру, имеется код:

DataPerson dataPerson;
IEnumerable person = dataPerson.>Get(); 
// как я понял, метод Get() должен в person записать значение ссылочного типа 
// на реализующий интерфейс типа Person? Не представляю как реализовать это.
// В плане непонятны мне следующие вопросы: 

// 1. Где следует реализовать этот интерфейс? 

// 2. Не понимаю про двойное обобщение вида >,
// а именно каким образом это указать в методе Get()?

// 3. Не понимаю как вернуть интерфейс через метод.


Класс Person:

class Person 
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string fName, string lName)
    {
        FirstName = fName;
        LastName = lName;
    }
}


Класс DataPerson:

class DataPerson
{
    // как я примерно представляю объявление функции Get()
    public IEnumerable Get() 
        where T : IEnumerable 
    {
        // как реализовать, к сожалению не представляю
    }   
}


Как собственно реализовать метод Get() в классе DataPerson?
    


Ответы

Ответ 1



Ваш метод скорее всего должен быть объявлен как class DataPerson { public IEnumerable Get() where T : new() { } } т.к. реально у него всего один тип-параметр - тип выбираемых объектов. и использоваться как IEnumerable person = dataPersonGet(); Реализовать его можно двумя способами: Действительно создать что-то, что реализует интерфейс IEnumerable. Например, массив или список. Заполнить его и вернуть из метода: class DataPerson { public IEnumerable Get() where T : new() { var query = buildSomeQueryFor(typeof(T)); // построить запрос для выбора объектов типа T DataRow[] dataRows = selectSomeRowsFromDB(query); // var result = new List(); foreach (var row in dataRows) { result.Add(MapDataRowTo(row)); } return result; } private MapDataRowTo(DataRow row) where T : new () { var newObject = new T(); // map values from row to newObject // return return newObject; } } Второй способо - использовать ключевое слово yield: class DataPerson { public IEnumerable Get() where T : new() { var query = buildSomeQueryFor(typeof(T)); // построить запрос для выбора объектов типа T DataRow[] dataRows = selectSomeRowsFromDB(query); // foreach (var row in dataRows) { yield return MapDataRowTo(row); } } private MapDataRowTo(DataRow row) where T : new () { var newObject = new T(); // map values from row to newObject // return return newObject; } } Использование yield завернет ваш метов в обертку-IEnumerable, которая будет возвращать элементы по мере обращения к ним из вызывающего кода. Т.е. выполнение метода Get будет происходить кусками, от одного вызова yield к следующему. В MSDN есть достаточно подробная документация по этой фиче языка.

Ответ 2



Как собственно реализовать метод Get() в классе DataPerson? class DataPerson { public IEnumerable Get() { return new List() { new Person(), new Person() }; } // или так public IEnumerable Get() { return new[] { new Person(), new Person() }; } }

среда, 12 февраля 2020 г.

Создание меню toolbar (три точки)

#java #android #интерфейс


Доброго времени суток. Подскажите пожалуйста, как создать меню в виде трех точек
в тулбаре. До этого создавал меню так:

public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }


Но это вызов через функциональную клавишу.
Также еще хотелось бы узнать как разместить иконку перед названием приложения в тулбаре?
Спасибо.

UPD
Решение нашел в соответствии с этой статьей.
    


Ответы

Ответ 1



В три точки (Overflow) убираются элементы меню со значениями ifRoom/never атрибута app:showAsAction. ifRoom элементы убирутся только если не поместятся в тулбар. иконку ставить как-то так: toolbar.setIcon(R.drawable.ic_launcher);

Ответ 2



Проблема отображения в ActionBar 3-х точек на андроид устройствах у которых есть hardware menu button уже редко, но все же встречается. Я для своего Samsung GT-i8552 применял в методе onCreate() следующую конструкцию: try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if (menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (Exception ignored) { } Решение тогда нашел где-то на просторах en.SO. P.S.: Но все же потом перешел на Toolbar, хотя для старых версий андроид присутствовала проблема - не было тени под тулбаром на андроид ниже 5.0. Так что дело вкуса.

суббота, 8 февраля 2020 г.

Как сделать Material Design Календарь на Android (см. скриншот)?

#android #интерфейс #material_design #toolbar




Как сделать такой Material Design Календарь под Android?  Есть ли какие-нибудь библиотеки?
Интересует именно дизайнерское решение. 
    


Ответы

Ответ 1



Всё, что на скриншоте сделано с помощью библиотеки Android Design Support Library от гугла. В данном случае эта разметка содержит: CoordinatorLayout, а в нём AppBar, а в нём CollapsingToolbarLayout, а в нём Toolbar и (наверное) GridView (для календаря) В CoordinatorLayout также еще RecyclerView (или ScrollView) и FloatingActionButton

среда, 5 февраля 2020 г.

Не выходит правильно наследовать интерфейс C#

#c_sharp #интерфейс


Есть интерфейс IHost

public interface IHost 
         where TAddress : IAddress 
         where TPingResult : IPingResult
{
    TAddress HostAddress { get; set; }
    TPingResult Response { get; set; }
    void SendRequest();
}


Затем его наследует ITCPHost

public interface ITCPHost: IHost 
{

}


И я реализую интерфейс ITCPHost в классе TCPHost

public class TCPHost : ITCPHost
{
    public ITCPAddress HostAddress { get; set; }
    public ITCPPingResult Response { get; set; }
    public Uri Uri { get; set; }

    public TCPHost(IPingResult response, IAddress address)
    {
        Response = (ITCPPingResult) response;
        HostAddress = (ITCPAddress) address;
    }

    public void SendRequest()
    {
        Метод что-то делает, не важно что...
    }


Затем я использую этот класс:

private static readonly Pinger.Pinger Pinger = new Pinger.Pinger();
private static readonly TCPPingResult Result = new TCPPingResult();
private static readonly TCPAddress Address = new TCPAddress("8.8.8.8",80);
private static readonly TCPHost Host = new TCPHost(Result, Address);
public PingHost()
{
    Pinger.PingEvent += NewPingHandler;
    Pinger.Ping(Host, 1); /* === ОШИБКА === */
}


В предпоследней строке кода выдает ошибку


  Severity  Code    Description Project File    Line    Suppression State
  Error   CS1503  Argument 1: cannot convert from 'ProtocolPinger.Hosts.TCPHost'
to 'ProtocolPinger.Hosts.IHost'  ProtocolPinger  D:\Projects\Visual Studio\ProtocolPinger\ProtocolPinger\Program.cs
 27  Active


Почему он не принимает наследника интерфейса? В чем ошибка?

Сигнатура метода Ping:

public void Ping(IHost host, int period)

    


Ответы

Ответ 1



Все дело в том, что IHost и IHost - это разные интерфейсы. Для того, чтобы первый можно было скастовать ко второму - надо сделать его ковариантным: interface IHost. Но в таком случае типы-параметры можно будет использовать только в качестве выходных (на что и намекает ключевое слово out): public interface IHost where TAddress : IAddress where TPingResult : IPingResult { TAddress HostAddress { get; } TPingResult Response { get; } void SendRequest(); } Если же вам нужны именно входные параметры, то задача решения не имеет, потому что IAddress невозможно привести к ITCPAddress в общем случае.

Обращение к методу, который не реализован в интерфейсе

#java #ооп #интерфейс


Есть интерфейс:

public interface Animal {
    void eat();
    void sleep();
    void go();
}


Есть 2 класса животных (представлен 1):

public class Tiger implements Animal {
    private int x; //координаты нахождения
    private int y;

   public Tiger(int x, int y {
      this.x = x;
      this.y = y;
   }

   @Override
   public void eat() {}

   @Override
   public void sleep() {}

   @Override
   public void go() {}

   public int getX() {
       return x;
   }

   public int getY() {
       return y;
   }
}


И класс Locator

public class Locator {
   private int x;
   private int y;

   public Locator(int x, int y) {
       this.x = x;
       this.y = y;
   }

   public void find(Animal animal) {
       /**
        * Метод сравнивает координаты локатора и координаты животного.
        * Если координаты совпадают, выводится сообщение
        */
   }
}


Нужно в методе find класса Locator обратиться к animal.getX().
Как это сделать, не изменяя интерфейс и не используя явное приведение типов ((Tiger)animal).
И вообще, возможно ли это?
    


Ответы

Ответ 1



Никак. Возможно, стоит расширить интерфейс Animal или ввести новый, в котором будут предоставляться координаты животного.

Ответ 2



Отрефакторить и сделать Move Method для getX и getY. Если Вам нужно getXXXX() вызывать у Animal, значит эти методы должны быть именно там. А еще лучше перенести туда метод find(). Тогда полиморфизм будет реализован в полной мере. Совет: Книга Рефакторинг Мартина вам в помощь! Очень полезная!

пятница, 31 января 2020 г.

Почему когда реализуется метод из интерфейса, он должен быть объявлен как public?

#java #интерфейс


Почему когда реализуется метод из интерфейса, он должен быть объявлен как public? 
    


Ответы

Ответ 1



Потому, что интерфейс для того и предназначен, что бы гарантировать наличие публичных методов, которыми смогут пользоваться внешние для класса пользователи. А каким образом будут реализованы эти публичные методы, в том числе, какие они будут использовать методы приватные - это ваше личное дело.

Что такое Interface в C#? [дубликат]

#c_sharp #интерфейс


        
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            Отличия абстрактного класса от интерфейса (abstract class
and interface)
                                
                                    (12 ответов)
                                
                        
                                Закрыт 2 года назад.
            
                    
Изучаю C#. Никак не могу понять смысл интерфейсов. Примеры, которые приводятся на
тех или иных ресурсах не дают мне полного понимания смысла интерфейсов. 
Что я понял:


В интерфейсах объявляются методы и свойства(как и в обычном классе)
Если класс наследуется от интерфейса, он обязан реализовать все методы интерфейса
Интерфейсы желательно начинать с буквы I - IComparable (желательно, но не обязательно)


НО, остается непонятной вещь - мне все равно надо реализовывать все методы, которые
я наследую, что не ведет к уменьшению количества кода, а даже наоборот. Пример взятый
из интернета

public interface IPizza
{
    public void Order();
}

public class PepperoniPizza : IPizza
{
    public void Order()
    {
        //Order Pepperoni pizza
    }
}

public class HawaiiPizza : IPizza
{
    public void Order()
    {
        //Order HawaiiPizza
    }
}


Если смотреть от обратного, то я не просто создаю методы в каждом классе, но еще
и объявляю непонятный интерфейс и наследую от него свои классы, что только увеличило
мой код... Код аккуратно вставить не получилось... Прошу помочь разобраться.
    


Ответы

Ответ 1



Воспринимайте интерфейс, как контракт на реализацию определённых методов в несвязанных классах. Грубо говоря, наследуя класс от интерфейса вы обязуетесь реализовать в этом классе определённые методы, при этом сами классы могут иметь совершенно различную "родословную". В итоге, в любом методе, где вы получите экземпляр класса реализующего интерфейс, вы сможете вызвать нужный вам метод не заботясь о том, что за класс вам прислали. Например, у вас есть система, которая отвечает за то, чтобы давать пинка каждому, кто проходит мимо. Чтобы не реализовывать в этой системе кучу ифов с проверкой на классы, чтобы понять каким образом пинок должен влиять на этот объект (лёгкий - подбрасывать, тяжёлый - толкать и т.д.) - вы создаёте интерфейс IPushable, который говорит, что реализующий его класс имеет метод PushIt(float velocity). А всю логику по применению ускорения от пинка передаёте в сами классы, которые реализуют этот интерфейс. Сама же система получает вошедший объект через какой-нибудь метод вроде public void ObjectIn(object obj). В этом методе делает проверку if (obj is IPushable) и если она истина - то со всей своею первобытной яростью даёт объекту пинка, через приведение типов var pushable = obj as IPushable; pushable.PushIt(velocity); Таким образом вы сможете пинать хоть коробку, хоть слона, хоть птицу Говорун, отличающуюся умом и сообразительностью. При этом все эти сущности между собой никак не связаны, а пинающая система понятия не имеет кого она там пнула.

среда, 29 января 2020 г.

Почему все переменные в интерфейсе являются final?

#java #ооп #наследование #интерфейс


И всетаки, почему все переменные в интерфейсе являются final? Для чего это ключевое
слово тут? В чем его смысл?

Для чего вообще это ключевое слово там?

Пусть бы они были не final! 

Что тогда?
    


Ответы

Ответ 1



Интерфейс определяет поведение объектов, а не конкретную реализацию. Если бы мы могли переопределять значения в дочерних интерфейсах или классах, реализующих этот интерфейс, то часть нашего интерфейса становилась бы частью конкретной реализации, что нарушало бы исходное понятие термина "интерфейс". Поскольку создавать экземпляры интерфейса нельзя и интерфейс не должен быть связан с конкретной реализацией, то неявно используется ключевое слово static (то есть данное поле определено в контексте, где нет никаких объектов). Отсутствие модификатора final также приводило бы к неоднозначности и путанице, поскольку каждый класс/интерфейс мог бы по своему усмотрению изменять это значение, что влияло бы на другие классы/интерфейсы. Но тут стоит заметить, что неизменяемость характерна для примитивных типов данных и immutable классов, для остальных же классов - final гарантирует только неизменяемость ссылки на область памяти, в которой расположен объект. Поля самого объекта при этом могут быть изменяемы. Если предположить возможность, что интерфейс может иметь нестатические изменяемые поля, то тогда бы возникла проблема с ромбовидным наследованием (diamond inheritance). Допустим, есть интерфейс A, в котором определено поле int v = 10. От этого интерфейса наследуются два других интерфейса B и C, каждый из которых переопределяет нашу переменную v (например, в B имеем значение 15, а в C - 20). Теперь мы определяем еще один интерфейс D, который наследуется от B и C. Тогда возникает вопрос: какое значение поле v должно унаследовать?

Ответ 2



final использует для того что бы переменному давали значение только один раз. К примеру: Если классу дали final тогда нельзя из этого класса создать подкласс. Если в классе есть методы с final. И вы создаете подклассы, Вы не сможете Переписать (Overwrite) этот метод. Это удобно, когда Вам не хочется что бы метод переписивали, и использовали в других целях. Примеру, функция sin(x). Если переменная имеет final, тогда вы можете передать значение этому переменному только 1 раз. Далже компилятор не дасть изменять значение. Это Удобно когда нужно объявлять константы. Что бы не чайно не изменить значение Переменной-константы. К примеру, pi = 3.1415

Зачем нужны ссылки на интерфейсы

#c_sharp #интерфейс


Есть программа, в которой я использую ссылки на интерфейсы. Грубо говоря. У меня
есть интерфейс IRoom, в которой есть интерфейс ITableList, с методами взаимодействия
со столами, в котором есть интерфейс ITable со всеми свойствами стола.


Зачем разработчики сделали так, если можно было использовать объекты в объектах? 
Где разработчики реализовали все методы интерфейсов, если я работаю лишь с ссылками
на интерфейс?
Просто необходимо реализовать подобное приложение и пытаюсь понять, зачем в данном
сделали именно так. 



Это интерфейс Позиций


Это интерфейс Список позиций взаимодействия с Позициями


Это интерфейс всего, там же и есть взаимодействие со Списком позиций


Это код взаимодействия sec - ISecurity, Positions - IPositionList, GetLast.... -
IPosition
    


Ответы

Ответ 1



Потому что под интерфейсом может скрываться экземпляр любого класса, реализующего этот интерфейс, и при необходимости его можно легко подменить (например в целях тестирования или чтобы изменить поведение). В случае с экземпляром конкретного класса подменить его на экземпляр какого-то другого класса уже нельзя. Под каждым интерфейсом скрывается какая-то конкретная реализация, в которой и определены необходимые методы. Например: interface IFoo { IBar Bar { get;set; } // прочие свойства и методы } class Foo : IFoo { public IBar Bar { get; set; } } var foo = new Foo(); // здесь мы присваиваем свойству Bar переменную класса Bar, в котором // уже определены все методы, указанные в интерфейсе IBar foo.Bar = new Bar();

Ответ 2



Есть такая штука, Принцип инверсии зависимостей - про него можно легко нагуглить. Интерфейсы являясь абстракцией и помогают реализовывать этот принцип. Используя интерфейсы программу можно сделать более гибкой и легко тестируемой. Интерфейс это контракт - он гарантирует, что класс реализующий его будет содержать описанные в интерфейсе методы - так что вся реализации интерфейсов находится непосредственно в классах. Ну как это делается, вам уже в соседнем ответе рассказали. Не буду повторяться. То что вы поняли под ссылкой на интерфейс - это просто конструкция языка, подразумевающая, что в этом поле будет хранится ссылка на любой класс реализующий этот интерфейс.

Interface с реализацией

#java #интерфейс


Я во всех учебниках видел, читал, тестировал interface с методами без реализации.
Но вот копаюсь в дереве и тут есть методы с реализацией default. Это как понять? То
есть можно реализовать интерфейс с реализацией??? Спасибо.
    


Ответы

Ответ 1



Можно определить интерфейс с реализацией. Эта возможность появилась в Java 8, в более ранних версиях она была недоступна. Вот пример реализации такого интерфейса: interface Test { default int test(int i) { return i; } } Если в классе, реализующем этот интерфейс, метод не переопределяется, то будет использована дефолтная реализация из интерфейса. Фактически, начиная с Java 8, интерфейс приобрёл некоторые черты обычного класса и стало возможным реализовать некий аналог множественного наследования.

Ответ 2



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

вторник, 28 января 2020 г.

Зачем нужны интерфейсы?

#php #интерфейс


Друзья, неоднократно задавался вопросом и задавал вопрос здесь, беспокоит и не даёт
покоя мысль о том, зачем нужны интерфейсы в php на пример. 
Есть кучи примеров, где объяснятся лишь только то что, они задают жёстко типизированную
структуру для других классов которые имплементируют и обязаны реализовывать публичные
методы, но толку, неужели профит только в этом, бороздя статьи по интерфейсам были
такие мнения что они позволяют обойти НЕмножественное наследование, то есть как? Объясните
пожалуйста, элементарный пример связи, как это происходит? 
Допустим есть интерфейс с одним методом. Имплементирующие его классы реализуют его
под свои нужды как им хотелось бы, но везде по разному, и это всё? Допустим наследовались
от того класса, который имплементировал интерфейс, дальше что?
Обновление
game();
        }

    public

    function to(outlol $outlol)
        {
        echo $outlol->game();
        }
    }

$obj = new anon();
$obj->you(new inlol());
echo "
"; $obj->to(new outlol()); echo "
"; Вернёт соответствующие строки, это и есть пример реализации интерфесов?


Ответы

Ответ 1



С интерфейсами можно решать много различных проблем в тех языках, где нет утиной типизации. Например. Можно объявить интерфейс, который будет описывать вывод элемента на экран. Дальше, написать несколько классов, которые реализуют этот интерфейс. Потом создать общую функцию вывода, которая будет получать одним с параметров указатель на класс/объект вывода. Если бы интерфейсов не было, пришлось эти все классы наследовать от одного общего предка. А это не всегда возможно. И если нужно стороннему классу добавить подобную функциональность - очень быстро пишется наследник с нужной реализацией. Второй плюс интерфейсов - класс может реализовывать много интерфейсов. Это актуально там, где нет множественного наследования. Третий плюс интерфейсов - междуязыковое общение (я правда не знаю, работает ли это в php, но точно работает в C/C++, Delphi, .NET). Интерфейс может быть описан в одном месте, а реализован на совсем другом языке. И это не мешает использовать его. Сама Windows активно использует интерфейсы.

Ответ 2



Рассматривайте интерфейс как контракт для класса на реализацию ряда методов. Смотреть нужно не со стороны самого класса, реализующего интерфейс, а со стороны классов, которые его используют. Если какой-то класс реализует интерфейс, то другие классы будут уверены, что в этом классе есть все методы, перечисленные в интерфейсе, и они могут их использовать. В качестве примера можно привести интерфейс Дверь. Всё, что нужно знать программе, использующей Дверь, это то, что её можно открыть и закрыть. При этом совершенно не важно, будет ли это обычная дверь, двустворчатая двеь или дверь банковского сейфа. При этом принципиальное отличие от наследования в данном случае состоит в том, что класс, реализующий интерфейс Дверь, может реализовывать другие интерфейсы, и даже наследоваться от какого-нибудь класса, избегая при этом проблем множественного наследования. По поводу множественного наследования. Предположим у нас есть классы A и B, в каждом из которых реализован метод doSth(). От них наследуется класс C. При этом возникает проблема: какой метод вызывать при вызове C.doSth() - A.doSth() или B.doSth()? Ведь оба метода унаследовались, и теперь каждый раз при вызове C.doSth() нужно явно указывать, метод какого из классов-предков использовать. Совсем другое дело если A и B интерфейсы. Если класс C реализует интерфейсы A и B, то в нём гарантированно будет метод doSth(), при этом не будет никаких коллизий, так как в интерфейсах нельзя реализовывать методы.

пятница, 24 января 2020 г.

Kotlin. Перегрузка методов под тип Null

#kotlin #интерфейс #null


Добрый день.
Пытаюсь реализовать интерфейс примерно такого вида:

interface IDataConversions {
    fun setData(value: Boolean?)
    fun setData(value: Byte?)
    fun setData(value: Short?)
    fun setData(value: Int?)
    fun setData(value: Float?)
    fun setData(value: ByteArray?)
    fun setData(value: String?)
}


Однако заметил, что в таком случае придется в каждом методе проверять на Null

Есть возможность в Kotlin реализовать что-то типа такого? : 

interface IDataConversions {
    fun setData(value: "какой то Null тип")
    fun setData(value: Boolean)
    fun setData(value: Byte)
    fun setData(value: Short)
    fun setData(value: Int)
    fun setData(value: Float)
    fun setData(value: ByteArray)
    fun setData(value: String)
}

    


Ответы

Ответ 1



Также, как и в джаве, при перегрузке будет браться сначала более конкретный тип. Выглядит так, что вам просто нужно перегрузить метод с параметром Any?: interface IDataConversions { fun setData(value: Any?) fun setData(value: Boolean) fun setData(value: Byte) ... }

четверг, 23 января 2020 г.

Android и масштабирование элементов

#java #android #listview #интерфейс #android_layout


Есть ли способ пропорционального масштабирования элементов интерфейса? Поясню на
примере: если при запуске на экране 100х200 помещаются 5 пунктов ListView, то при запуске
на экране 200х400 помещались все те же 5, а размеры элементов, включая и размеры шрифтов,
увеличивались пропорционально.
    


Ответы

Ответ 1



Заведите эталонные размеры в виде констант При запуске на к-л девайсе получайте его размеры и вычисляйте коэффициент отличия полученных размеров от эталонных. В getView адаптера списка назначайте высоту элементов равной эталон * коэффициент. То же делайте для шрифтов etc.

Ответ 2



Параметр android:layout_weight Например:

Вытягивания виджетов

#cpp #qt #gui #qt5 #интерфейс


Я работаю в qt5. Эта кнопка("addButton")  отвечает за создание этих кнопок("GreenButton")
. В слоте addButton создается GreenButton:

void SearchForm::on_AddButtonButton_pressed()
{
     Editor.pobj = new GreenButton(this);
}


Код GreenButton:

QPoint delta;

    void mousePressEvent(QMouseEvent* e)
        {
            delta.rx()   = e->pos().x();
            delta.ry()   = e->pos().y();
        }

        void mouseMoveEvent(QMouseEvent* e)
        {

            setGeometry(
                    geometry().x()  + e->pos().x() - delta.x(),
                    geometry().y()  + e->pos().y() - delta.y(),
                    width(),
                    height()
            );
        }

        explicit GreenButton(QWidget *parent = 0 ) 
        {


            setGeometry(QCursor::pos().x() - parent->geometry().x() - 8,
                        QCursor::pos().y() - parent->geometry().y() - 8,
                        111,
                        111
            );
            show();
            QMouseEvent event1(QEvent::MouseButtonPress,  this->pos(), Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);

            QApplication::sendEvent(this, &event1);
        }


GreenButton создается , перемещается мышью. Как сделать чтобы при нажатии на addButton
и не отпускании ее перемещался GreenButton?
Я думал поможет искуственное создание событий, но не помогло:

QMouseEvent event1(QEvent::MouseButtonPress,  this->pos(), Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
QApplication::sendEvent(this, &event1);

    


Ответы

Ответ 1



Т.к. у нас есть форма, на которой размещена «добавляющая кнопка», и на ту же форму мы добавляем другие кнопки, предлагаю воспользоваться следующей стратегией: Устанавливаем фильтр сообщений на нашу «добавляющую» кнопку. Будем ловить нажатие и перемещение мыши. Во время нажатия будем создавать новую кнопку и запоминать её. Во время появления события перемещения, будем перемещать нашу кнопку. Всё это довольно просто реализовать: MainWindow.h: #pragma once #include class QPushButton; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* parent = 0); bool eventFilter(QObject* obj, QEvent* event); private: QPushButton* m_CurrentButton; }; MainWindow.cpp: #include #include #include #include #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto widget = new QWidget(this); auto addButton = new QPushButton("add", widget); setCentralWidget(widget); addButton->installEventFilter(this); } bool MainWindow::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::MouseButtonPress) { auto mouseEvent = static_cast(event); m_CurrentButton = new QPushButton("new", centralWidget()); auto localPoint = mapFromGlobal(mouseEvent->globalPos()); m_CurrentButton->move(localPoint); m_CurrentButton->show(); return true; } if(event->type() == QEvent::MouseMove) { auto mouseEvent = static_cast(event); auto localPoint = mapFromGlobal(mouseEvent->globalPos()); m_CurrentButton->move(localPoint); return true; } return QObject::eventFilter(obj, event); } На базе этого кода, Вы можете адаптировать свой код.

Ответ 2



Сначала решение: class MyForm: public QWidget { QTimer * Ticker ; QPushButton * MovingButton; public: MyForm(QWidget * parent = nullptr) : QWidget (parent ) , Ticker (nullptr) , MovingButton(nullptr) { Ticker = new QTimer(this); connect(Ticker, &QTimer::timeout, this, &MyForm::moveButton); } ~MyForm() { stopMoving(); } public slots: void addPressed() { MovingButton = new QPushButton(this); // настраиваем новую кнопку MovingButton->show(); // Начинаем перемещение через пол секунды Ticker->setSigngleShot(true); Ticker->setInterval(500); Ticker->start(); } void addReleased() { stopMoving(); // останавливаем движение } void moveButton() { if(MovingButton) { if(Ticker->singleShot()) // ускоряем таймер до 30 мс { Tciker->setSignleShot(false); Ticker->setInterval(30); } // двигаем кнопку MovingButton->move(MovingButton->pos() + QPoint(8,8)); } } private: void stopMoving() { MovingButton = nullptr; Ticker->stop(); } }; Здесь addPressed() и addReleased() слоты которые должны быть подключены с сигналам кнопки AddButton pressed() и released() соответственно. Работает код следующим образом: В обработчике нажатия addPressed() создаем новую кнопку и запоминаем указатель на нее в MovingButton, потом стартуем таймер Ticker на пол секунды по окончании которого выполняем перемещение. Пол секунды нужно для того чтобы была пауза перед началом движения. В обработчике таймера Ticker moveButton() ускоряем таймер до 30 мс а также перемещаем текущую кнопку MovingButton если таковая имеется. В обработчике отпускания addRelease() просто зануляем указатель на перемещаемую кнопку MovingButton и останавливаем таймер Ticker - таким образом останаваливаем движение.

Ответ 3



предложу необычный вариант: - AddButton сделать наследником от GreenButton - Как только AddButton кликнули, что означает добавление, AddButton меняет своё рисование, на рисование предка. То есть, начинает рисоваться, как GreenButton. - Новый AddButton на месте старого можно сделать как в начале таскания, так и по его окончанию - зависит от сценария