Различия между классом и объектом?
====================================

 К своему стыду, внезапно, осознал, что не понимаю разницы между классом и объектом.  
  

Т.е. чисто теоретически понимаю, что объект это экземпляр класса, т.е. класс это как бы заготовка, а уже объект это уже «вещь», с которой можно непосредственно работать.  
  

Но тогда почему (если рассматривать вопрос в PHP), я все-таки могу работать с методами класса ( ClassName::MethodName() ), так же как и с методами объекта ( $c = new ClassName; $c->MethodName() ), хотя, в первом случае никакого объекта не создано.  
  

Или, в данном случае, класс это просто как бы группа глобальных функций в своём «пространстве имен», которые не требуют «персонализации» путем задания уникальных значений их свойств?  
  

Поиск в гугле почему-то не помог, в основном приводятся аналогии вида «Класс — чертежи машины, объект — сама машина», но ни слова о практическом применении.  
  

Заранее благодарен за разъяснения, а то сия каша в голове уже начинает напрягать =) 

 Класс = срособ организации полей, методов и пр. = инкапсулированный «кусок» функциональности, описание структуры будущих объектов + своё пространство имён внутри.  

  

Статическая составляющая класса — static-методы и static-поля — это логический способ организации функциональности, общей для любого объекта выделенной сущности. Тут значение имеет логическая составяющая — например, статический метод Parse есть и в классе int, и в классе Guid — но его функциональность различна и соответствует выделенной сущности. Для static-составляющей класса, в принципе, его можно воспринимать как пространство имён. Но пространсто имён нельзя инициализировать, нельзя создать объект пространства имён.  

  

Объект = экземпляр класса = объект, типом которого является какой-то класс = класс после инициализации = сущность в памяти, обладающая поведением, способная изменять своё состояние. 

 Может быть вам легче будет понять, если вы будете думать о классе как о наборе функций, а об объекте как о наборе данных.   

  

Некоторые функции в классе могут быть использованы только с набором данных (т.е. объектом), который передается неявно, когда вы указываете `$object->method().   

  

Другие функции не требуют объекта, поэтому могут быть вызваны напрямую из класса.  

  

С этой точки зрения очень логично выглядит Python, где у любого метода есть явный аргумент self, указывающий на объект, из которого был вызван метод. А запись object.method(5) является краткой записью ObjectClass.method(object, 5). 

 Я придумал свою дурацкую аналогию.  

  

Класс — это бог, который есть всегда. И бог по образу и подобию своему создаёт экземпляры — человеков. Каждый человек наделён своим набором свойств (рост, вес, ...) и методов (плавать, ходить, летать, ...). А бог в свою очередь наделён общими для всех методами: принимать мольбы, карать, посылать манну небесную и сотворить чудо. Эти методы могут быть приватными. Т.е. бог например может принимать мольбы только людей, а не марсиан. А вот сотворить чудо может как для людей, так и для марсиан — ему не жалко.  

  

: ) 

 Класс — чертеж, объект класса — машина, собранная по этому чертежу.  

  

Статический метод — это некое устройство (пусть в нашем случае будет GPS-навигатор), которое поставляется вместе с чертежом и представлено в каждой машине, построенной по этому чертежу. Устройство это никак не задействует машину, и работает само по себе.  

  

Вы можете бегать с GPS навигатором не построив машины.  

  

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

 Без реализации класса (создания объекта) Вы можете работать только со статическими методами/свойствами класса. Если на примере упомянутой машины — класс описывает, что это такое, а реализация (instance) класса — соответственно, реализовывает какую-то конкретную машину.  

  

Простейший миниатюрный пример:  

class Car {
    public $brand = NULL;
}
$car = new Car;
$car->brand = 'VW';
$car2 = new Car;
$car2->brand = 'Жигули';

```
  

В итоге у нас 2 машины — VW и Жигули. Обе — экземпляры класса машина (Car). Без создания экземпляра класса Вы не зададите брэнд — нечему его задавать, собственно.  

  

Ну это если примитивы на пальцах.  

А вообще — вот, держите: [про ООП на php.su](http://php.su/learnphp/phpoo/) 

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

  

Далее, к классу можно добавить статические методы и поля. Здесь уже сам класс будет иметь возжность хранить свое состояние и выполнять действия. В большинстве случаев (но не во всех) это требуется для контроля над производством объектов этого класса (паттерн Синглетон, Фабрика и т.п.).  

  

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

  

Все это понимание придет с опытом написания программ, просто нужно думать метафорами. 

 Всё просто. В случае класса это просто некое описание методов, полей и т.д. Когда мы вызываем любой метод класса, то в аргументах мы неявно передаем указатель this.  

То есть в реальности вызов  

a->b(arg);  

выглядит как   

b(arg,a);  

А static методы они отличаются от обычных тем, что у них нету этого неявного аргумента this