Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
899
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Члены Общественного интерфейсов C#
В C#, при реализации интерфейса все члены являются неявно открытыми. Не было бы лучше , если бы мы могли указать модификатор доступности ( protected , internal, кроме private , конечно), Или мы должны просто использовать абстрактный класс вместо этого?
Если интерфейс является внутренним, то все его члены будут внутренними для assembly. Если вложенный интерфейс защищен, только подклассы внешнего класса могут получить доступ к этому интерфейсу.
Внутренние члены для интерфейса вне его объявления assembly были бы бессмысленны, как и защищенные члены для интерфейса вне его объявления внешнего класса.
Суть интерфейса заключается в описании контракта между типом реализации и пользователями интерфейса. Внешние абоненты не будут заботиться и не должны заботиться о реализации, для чего существуют внутренние и защищенные члены.
Для защищенных членов, вызываемых базовым классом, абстрактные классы - это способ задания контракта между базовыми классами и классами, которые наследуют от них. Но в этом случае детали реализации обычно очень важны, если только это не вырожденный чистый абстрактный класс (где все члены абстрактны), в котором защищенные члены бесполезны. В этом случае перейдите к интерфейсу и сохраните один базовый класс для реализации выбранных типов.
Вы можете скрыть реализацию интерфейса, явно указав имя интерфейса перед именем метода:
public interface IInterface {
public void Method();
}
public class A : IInterface {
public void IInterface.Method() {
// Do something
}
}
public class Program {
public static void Main() {
A o = new A();
o.Method(); // Will not compile
((IInterface)o).Method(); // Will compile
}
}
Все ответы здесь более или менее говорят о том, что именно так и должны быть интерфейсы, они являются универсальными публичными спецификациями.
Поскольку это самая обсуждаемая тема, позвольте мне опубликовать два отличных ответа, которые я нашел на SO, когда этот вопрос всплыл у меня в голове.
Этот ответ дает пример того, как может быть бессмысленно иметь неоднородные спецификаторы доступа для членов интерфейса в производных классах. Код всегда лучше технических описаний.
На мой взгляд, самое ужасное в принудительных открытых членах интерфейса - это то, что сам интерфейс может быть внутренним для assembly, но члены, которые он выставляет, должны быть открытыми. Джон Скит объясняет здесь, что это по дизайну печально .
Это поднимает вопрос, почему интерфейсы не были разработаны, чтобы иметь непубличные определения для членов. Это может сделать контракт гибким. Это довольно полезно при написании сборок, где вы не хотите, чтобы определенные члены классов были доступны за пределами assembly. Я не знаю почему.
Интерфейс-это контракт, которого придерживаются все реализующие классы. Это означает, что они должны придерживаться всего этого или ничего из этого.
Если интерфейс является общедоступным, то каждая часть этого контакта должна быть общедоступной, иначе это будет означать одно для друзей / внутренних классов и другое для всего остального.
Либо используйте абстрактный базовый класс, либо (если это возможно и практично) метод внутреннего расширения на интерфейсе .
Вы можете скрыть почти весь код, реализованный интерфейсами к внешним сборкам.
interface IVehicle
{
void Drive();
void Steer();
void UseHook();
}
abstract class Vehicle // :IVehicle // Try it and see!
{
/// <summary>
/// Consuming classes are not required to implement this method.
/// </summary>
protected virtual void Hook()
{
return;
}
}
class Car : Vehicle, IVehicle
{
protected override void Hook() // you must use keyword "override"
{
Console.WriteLine(" Car.Hook(): Uses abstracted method.");
}
#region IVehicle Members
public void Drive()
{
Console.WriteLine(" Car.Drive(): Uses a tires and a motor.");
}
public void Steer()
{
Console.WriteLine(" Car.Steer(): Uses a steering wheel.");
}
/// <summary>
/// This code is duplicated in implementing classes. Hmm.
/// </summary>
void IVehicle.UseHook()
{
this.Hook();
}
#endregion
}
class Airplane : Vehicle, IVehicle
{
protected override void Hook() // you must use keyword "override"
{
Console.WriteLine(" Airplane.Hook(): Uses abstracted method.");
}
#region IVehicle Members
public void Drive()
{
Console.WriteLine(" Airplane.Drive(): Uses wings and a motor.");
}
public void Steer()
{
Console.WriteLine(" Airplane.Steer(): Uses a control stick.");
}
/// <summary>
/// This code is duplicated in implementing classes. Hmm.
/// </summary>
void IVehicle.UseHook()
{
this.Hook();
}
#endregion
}
Это позволит проверить код.
class Program
{
static void Main(string[] args)
{
Car car = new Car();
IVehicle contract = (IVehicle)car;
UseContract(contract); // This line is identical...
Airplane airplane = new Airplane();
contract = (IVehicle)airplane;
UseContract(contract); // ...to the line above!
}
private static void UseContract(IVehicle contract)
{
// Try typing these 3 lines yourself, watch IDE behavior.
contract.Drive();
contract.Steer();
contract.UseHook();
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
}
Интерфейсы не имеют модификаторов доступа в своих методах, оставляя их открытыми для любого подходящего модификатора доступа. Это имеет свою цель: он позволяет другим типам определить, какие методы и свойства доступны для объекта, следующего за интерфейсом. Предоставление им защищенных / внутренних средств доступа разрушает цель интерфейса.
Если вы твердо уверены, что вам нужно предоставить модификатор доступа для метода, либо оставьте его вне интерфейса, либо, как вы сказали, используйте абстрактный класс.
Я знаком с Java, а не с C#,, но с какой стати вам нужен частный член в интерфейсе? Он не мог иметь никакой реализации и был бы невидим для реализующих классов, поэтому был бы бесполезен. Существуют интерфейсы, определяющие поведение. Если вам нужно поведение по умолчанию, то используйте абстрактный класс.