Они совершенно разные. Наследование - это отношение "is-a" . Композиция представляет собой «has-a» .
Вы выполняете композицию, имея экземпляр другого класса C
в качестве поля вашего класса, вместо расширения C
. Хорошим примером, где состав был бы намного лучше, чем наследование, является java.util.Stack
, который в настоящее время распространяется java.util.Vector
. Это сейчас считается ошибкой. Стек "- это-НЕ-a" вектор; вам не разрешается вставлять и удалять элементы произвольно. Это должно было быть композиция.
К сожалению, слишком поздно исправить эту ошибку дизайна, так как изменение иерархии наследования теперь нарушит совместимость с существующим кодом. Если вместо наследования использовалась композиция Stack
, ее всегда можно было изменить, чтобы использовать другую структуру данных, не нарушая API .
Я очень рекомендую книгу Джоша Блоха Эффективная Java 2-е издание
Хороший объектно-ориентированный дизайн - это не либеральное расширение существующих классов. Ваш первый инстинкт должен составлять вместо этого.
См. Также:
Как альтернатива утиному вводу через
typeof date.getMonth === 'function'
можно использовать instanceof
оператор, т.е. Но это возвратит true для недопустимых дат также, например, new Date('random_string')
также экземпляр Даты
date instanceof Date
, Это перестанет работать, если объекты будут переданы через границы кадра.
обходное решение А для этого должно проверить класс объекта через
Object.prototype.toString.call(date) === '[object Date]'
Для всех типов я приготовил Объектную опытную функцию. Это может быть полезно для Вас
Object.prototype.typof = function(chkType){
var inp = String(this.constructor),
customObj = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9),
regularObj = Object.prototype.toString.apply(this),
thisType = regularObj.toLowerCase()
.match(new RegExp(customObj.toLowerCase()))
? regularObj : '[object '+customObj+']';
return chkType
? thisType.toLowerCase().match(chkType.toLowerCase())
? true : false
: thisType;
}
Теперь, можно проверить любой тип как это:
var myDate = new Date().toString(),
myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String
[ Редактирование идет 2013 ] на основе прогрессирующего понимания, это - лучший метод:
Object.prototype.is = function() {
var test = arguments.length ? [].slice.call(arguments) : null
,self = this.constructor;
return test ? !!(test.filter(function(a){return a === self}).length)
: (this.constructor.name ||
(String(self).match ( /^function\s*([^\s(]+)/im)
|| [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Some = function(){ /* ... */}
,Other = function(){ /* ... */}
,some = new Some;
2..is(String,Function,RegExp); //=> false
2..is(String,Function,Number,RegExp); //=> true
'hello'.is(String); //=> true
'hello'.is(); //-> String
/[a-z]/i.is(); //-> RegExp
some.is(); //=> 'ANONYMOUS_CONSTRUCTOR'
some.is(Other); //=> false
some.is(Some); //=> true
// note: you can't use this for NaN (NaN === Number)
(+'ab2').is(Number); //=> true
Вы могли проверить, существует ли функционально-специализированное к объекту Даты:
function getFormatedDate(date) {
if (date.getMonth) {
var month = date.getMonth();
}
}
Element.prototype
со спамом. There' s совершенно хорошее getElementsByClassName
метод, который делает то, что Вы хотите, но лучше.
– Raynos
11 January 2012 в 21:48
Как обозначено выше, является, вероятно, самым легким просто проверить, существует ли функция перед использованием его. Если Вы действительно заботитесь, что это Date
, и не только объект с getMonth()
функция, попробуйте это:
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
Это создаст или клон значения, если это будет Date
, или создайте недопустимую дату. Можно тогда проверить, недопустимо ли значение новой даты или нет.
На самом деле дата будет иметь тип Object
. Но можно проверить, имеет ли объект getMonth
метод и если это является вызываемым.
function getFormatedDate(date) {
if (date && date.getMonth && date.getMonth.call) {
var month = date.getMonth();
}
}
Функция getMonth()
, не GetMonth()
.
Так или иначе, можно проверить, имеет ли объект getMonth свойство путем выполнения этого. Это не обязательно означает, что объектом является Дата, просто любой объект, который имеет getMonth свойство.
if (date.getMonth) {
var month = date.getMonth();
}
Вместо всех обходных решений можно использовать следующее:
dateVariable = new Date(date);
if (dateVariable == 'Invalid Date') console.log('Invalid Date!');
я нашел этот взлом лучше!