Допустим, у меня есть номер телефона, который мои классы должны проверять и отслеживать, и по большей части телефонный номер - это просто строка, поэтому, пытаясь быть СУХОЙ, можно просто создать класс телефона и наследовать от строки. Так как я не могу сделать то, что является следующим лучшим подходом? Добавление строки в качестве частного члена и перегрузка равных/= операторов, чтобы она могла быть передана и задана как строка?Inheriting From Sealed Classes
ответ
Могу ли я предложить вам взять рекомендации Йоханнеса Рудольфа или К. Росса. Вы также можете просмотреть поведение ключевого слова implicit, которое позволит вам назначать String-подобным образом при выполнении проверки.
т.е .:
public class PhoneNumber {
private String number;
public PhoneNumber(String s) {
// validation code here, throw exception if not valid
number = s;
}
public static implicit operator PhoneNumber(String s) {
return new PhoneNumber(s);
}
}
предпочитает композицию над наследованием.
Вы хотите, чтобы ваш номер телефона был назначен из строки? Конечно, не потому, что следующий будет возможным, то:
Person.PhoneNumber = "FOO"
Нечто подобное чувствует себя более естественно:
Person.PhoneNumber = new PhoneNumber("015-123456");
Вы можете сделать пользовательскую проверку в конструкторе и дополнительно решите, что вы хотите быть неизменны (ок , строка тоже была бы неизменной)
Я бы создал класс PhoneNumber с частным членом строки, как вы предложили. Вы можете переопределить метод ToString(), если хотите обеспечить согласованное форматирование (например, (123) 123-1234 или что-то еще), вы можете добавить некоторую проверку на метод набора или конструктор, чтобы убедиться, что номер телефона имеет 10 цифр (если североамериканский номер).
Создание класса PhoneNumber позволяет вам расширить класс позже, если вам нужно. Например, вы можете улучшить проверку номера телефона, чтобы проверить наличие недопустимых кодов областей и вызвать ошибку, если код области не существует.
Одним словом, да, есть частный член. Однако вместо перегрузки назначения я бы предложил иметь статический элемент синтаксического анализа.
PhoneNumber p = PhoneNumber.Parse("704 - 576- 4000");
Это более стандартный и читаемый. Кроме того, даже если вы могли бы наследовать строку, я бы посоветовал это сделать, поскольку String имеет сложную внутреннюю функциональность, которая должна быть отделена от вашего класса. Кроме того, наследование из строки будет вызывать ряд методов, которые не имеют смысла для номера телефона (то есть: Concat, неточно сравниваются и т. Д.).
- 1. Inheriting from Canvas
- 2. Inheriting from std :: vector
- 3. Querying from Parse Classes
- 4. Inheriting defaultProps from superclass in React
- 5. Inheriting T from from Collection <T>
- 6. Cocos2d: accuing childs from other classes
- 7. Sealed класса в Scala
- 8. Sealed-Partial Class
- 9. Inheriting NSDecimalNumber
- 10. Inheriting System.Windows.Controls.Panel
- 11. Inheriting wx.grid.GridCellTextEditor
- 12. C++: Devirtualize Leaf Classes
- 13. Inheriting PyQt5 class
- 14. C# Sealed Предотвращение получения метода
- 15. Mocking Sealed Class with RhinoMocks
- 16. Inheriting NetworkInterface в C#
- 17. Inheriting InnerClass in java
- 18. nodejs: inheriting EventEmitter
- 19. Inheriting non-default
- 20. Inheriting Child Methods
- 21. Inheriting ConstructorArguments в Ninject
- 22. Inheriting События jQuery Model
- 23. Inheriting Eclipse Plug-in
- 24. Inheriting CSS Width
- 25. Flex Inheriting Забыл пользователь
- 26. constructor inheriting self python
- 27. TD Inheriting TABLE width
- 28. Inheriting F # Record
- 29. Java Classes To C# Classes
- 30. Netbeans. «Entiry classes from database» и Postgresql domains
Я понимаю, что, принимая Person.PhoneNumber = "Foo" и бросает исключение является лучшей практикой, то Person.PhoneNumber = новый PhoneNumber ("Foo"); бросая исключение для конструктора. Но это могут быть только мои звонки на фоне C++. –
Ваши звонкие колокола, как правило, правильные, но мы работаем в среде GC здесь, поэтому безуспешное создание объекта не представляет проблемы. Вы также можете сделать конструктор Person.PhoneNumber закрытым и предоставить статический метод PhoneNumber.Parse, который отвечает за создание экземпляра PhoneNumber и проверку строки. –