ООП Javascript против Java (или других, таких как PHP)

#javascript #oop

#javascript #ООП

Вопрос:

Я немного понимаю разницу между Javascript и Java, когда дело доходит до ООП. Я прочитал нижний абзац в книге по Javascript, которая у меня есть, но я не до конца понимаю, что это значит, можете ли вы подробнее объяснить и привести примеры, чтобы показать разницу между двумя языками?

«Во многих объектно-ориентированных языках программирования можно определить класс объектов, а затем создавать отдельные объекты, которые являются экземплярами этого класса».

Спасибо!

Ответ №1:

То, что большинство людей делают, это используют функции конструктора, например, так:

 function MyClass(a, b) {
    // Private instance properties
    var x = "secret";
    var y = "also secret";

    // Public instance properties
    this.a = a;
    this.b = b;

    // "Privileged" methods; can access private and public properties
    this.foo = function () {
        return x   " "   this.a;
    };
}

// "Public" methods; cannot access private properties
MyClass.prototype.bar = function () {
    return this.a   " "   this.b;
};

// Public shared properties; not recommended:
MyClass.prototype.w = "stuff";

// Static methods
MyClass.baz = function () {
    return "i am useless";
};
  

Затем вы могли бы использовать эту функцию конструктора следующим образом:

 var instance = new MyClass("hi", "Meen");

asssert.equal(instance.foo(), "secret hi");
assert.equal(instance.bar(), "hi Meen");
assert.equal(MyClass.baz(), "i am useless");

var also = new MyClass("hi", "Raynos");

instance.w = "more stuff";
assert.equal(also.w, "more stuff");
  

Если бы вы хотели использовать наследование, вы бы сделали что-то вроде:

 function Inherited(a) {
    // apply parent constructor function
    MyClass.call(this, a, "Domenic");
}
Inherited.prototype = Object.create(MyClass.prototype);

var inherited = new Inherited("hello there good chap");

assert.equal(inherited.a, "hello there good chap");
assert.equal(inherited.foo(), "secret hello there good chap");
assert.equal(inherited.bar(), "hello there good chap Domenic");
  

Комментарии:

1. Вы просматриваете «частные» и «привилегированные», не объясняя, что они являются просто локальными переменными в замыкании и определяют стоимость времени выполнения, а также мешают выполнению прототипного OO. Это две параллельные конструкции, и они не особенно хорошо работают вместе.

2. Микрооптимизации никогда не были важны в моем опыте выполнения ООП на JavaScript; возможность использовать один из четырех принципов ООП, а именно. гораздо важнее инкапсуляция.

3. В этом случае вам не нужен прототип OO. У вас должны быть просто фабрики, которые мутируют this . Также обратите внимание, что «инкапсуляция» соответствует второму определению в википедии .

4. Да, второе определение — это не то, что подразумевается под инкапсуляцией в контексте ООП, ср. blog.ploeh.dk/2011/05/24 /…

5. Meh, для этого вам не нужны локальные переменные, связанные с закрытием. Вы можете использовать разумное, хорошо документированное соглашение, такое ._internalName как внутреннее, недокументированное и, вероятно, изменяющееся или взрывающееся при прикосновении к коду, использующему «класс». Это дает вам инкапсуляцию и прототипический OO.

Ответ №2:

Объектно-ориентированный javascript очень прост.

Вы создаете объект.

 var Klass = {
  method: function () {

  },
  constructor: function() {

  },
  ...
};
  

И затем вы создаете экземпляр этого объекта с помощью прототипического наследования

 // instantiate
var o = Object.create(Klass);
// initialize
o.constructor();
  

Это отличается от классического OO, потому что любой объект может быть «классом» в javascript. и есть только одна цепочка наследования, цепочка прототипов.

Обычно в классических языках OO классы наследуются друг от друга, а экземпляры будут иметь отдельную цепочку наследования.

Также в классическом OO у вас есть два объекта: фактический объект класса и схема для экземпляра (т. Е. static ). Этого не существует в javascript, потому что есть только один объект, blueprint.

Отказ от ответственности: Object.create это ES5, поэтому вам нужна es5-shim для устаревших платформ.

Комментарии:

1. О, дорогой, не продвигай свой любимый недавно обнаруженный стиль прототипов как классов без хотя бы какого-либо заявления об отказе от ответственности… @Meen то, что делает Raynos, делается очень немногими людьми и является результатом какой-то статьи, которая стала популярной в течение последнего месяца; вы не увидите много кода JavaScript в дикой природе, подобного этому.

2. @Domenic Это практически одно и то же. Klass.constructor.prototype === Klass amp;amp; Constructor.prototype.constructor === Constructor . Это вопрос личного стиля, и я нахожу это намного более читаемым и элегантным, чем возня с конструкторами, .prototype и new . И на самом деле то, что я делаю, отражает примеры объектов es.next и классы es.next, сообщество ES отойдет от конструкторов. И, кроме того, помимо «Это не мой выбор стиля», есть ли что-то не так с конструкциями, которые я показываю?

3. Это совсем не одно и то же. Этот стиль отделяет инициализацию от создания с помощью этого конструктора, что является существенным отличием, и что более важно, этот стиль используется очень немногими людьми на планете. Субъективные мнения о удобочитаемости и элегантности перевешиваются тем, хочет ли OP, чтобы его код был доступен для чтения тем, кто не читал сообщение в блоге Раушмайера.

4. @Domenic meh, var KlassConstructor = Klass.constructor; var instance = new KlassConstructor(...); . Они одинаковы. И инициализация, и построение всегда были отдельными, new просто случается делать и то, и другое. Лично я бы сказал, что если кто-то не может прочитать код, тогда нужно изучить ES5.

5. Примеры и Wirfs-предложение Брока «grawlixey» активно обсуждается; будут ли они приняты в ES.Next, совершенно неясно, как и то, будет ли сообщество адаптироваться к чему-либо подобному. Классы ES.next заменяют что-то гораздо более похожее на конструкторы, чем на примеры, и, что более важно, акцент на частных именах признает важность достижения инкапсуляции, так или иначе; в ES5 это достижимо только с помощью замыканий.

Ответ №3:

В Java вы можете создать класс, используя class ключевое слово. Класс — это схема для его экземпляров (объектов).

например

 class AClass { // AClass is a class
    AClass() { } //this is the constructor which will be used to create instances of this class
}
  

А затем создайте и экземпляр класса:

 AClass obj1 = new AClass(); // an instance of the class AClass
AClass obj2 = new AClasss(); //another instance of the class AClass
  

Итак, каждый объект в Java является экземпляром некоторого класса. И у вас может быть много разных экземпляров класса, но у вас не может быть никакого объекта без класса, который действует как их схема.

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

В Javascript я в основном создаю объекты следующим образом:

 var obj = { };
  

Итак, мне не нужно создавать какой-либо класс, чтобы фактически создать объект.

Комментарии:

1. Ха-ха, простота вашего ответа заставляет меня смеяться :). 1