Доброго времени суток.
Прочитав пост VladimirJoy Создание простейшего приложения на Java, решил несколько развить начатую тему. Если вы знаете всю теорию ООП, но так и не поняли, с чего же начать писать свои классы с использованием полиморфизма и инкапсуляции, или же просто хотите поспорить на тему хорошего тона программирования на Java — прошу под кат.
И да, сразу уточню, я буду писать про написание приложения в текстовом редакторе. Никаких IDE, никаких автоматических сборок и запуска приложения по кнопочке play. Потому что используя IDE сложно понять, как Java запускает ваше приложение. И потому что это круто :)
Итак, давайте начнем с начала.
Надо создать файл с расширением .java. В этих файлах и будет содержаться наш с вами код. На каждый класс — по файлу. И да, уточнение, названием файла должно быть название класса, иначе ничего не заработает.
Ну создадим, для примера, файл с названием MyCoolClass.java, в который поместим код:
public class MyCoolClass{
public MyCoolClass(){
//Конструктор объекта
//Сюда пишем всякие разные присваивания и другие плюшки, которые хотим дать нашему объекту при рождении
}
public void someMethod(){
//Тут прописываем метод объекта. Ну например, можем его попросить вывести нам на экран чего нибудь
System.out.println("MyCoolClass object called a someMethod method!!");
}
public static void someStaticMethod(){
//Статичный метод, вызывается классом, а не его объектами.
}
}
Ну вот как-то так. Эдакие файлы можно группировать по папкам (а классы будут группироваться по package). Скомпилировать один такой фаил можно с помощью команды javac MyCoolClass.java, в результате получим .class фаил, который является байт-кодом. Вот .class то и будут считаны JVM и исполнены.
Уточнение — что бы правильно, со всеми зависимостями, скомпилировать приложение, содержащее в себе несколько packages и классов, можно использовать разные утилиты, например Ant (Google, Habrahabr).
Точка входа в программу — метод main(String[] args){}. С него то вся работа и начинается. Хорошим тоном считается начинать программу так(вот собственно и все, VladimirJoy, что вы донесли до общественности, кроме, конечно, рекламы и желания увидеть свою статью первой в Google):
public class Application {
public void init() {
//Тут наше приложение инициализируется. Создаются все нужные для работы объекты, делаются все проверки, добавляются разные плюшечки
}
public void run() {
//Тут наше приложение начинает свою работу.
}
public static void main(String[] args) {
Application application = new Application();
application.init();
application.run();
}
}
Повторюсь, методы init() и run() — просто хороший тон, и они необязательны. Все то, что вы пишете в них, можно поместить в main, если очень хочется.
Для проверки, опять же, компилируем:
javac Application.java
и запускаем
java Application
Это если у вас нет packages. Если они присутствуют, компиляция с помощью Ant, запуск:
java 'packageName.Application'
Теперь мы знаем, с чего начать. Давайте, например, напишем программу, в которой будет… Скажем, одна вселенная, содержащая 3 планеты, и у одной из планет будет 1 спутник, а у другой — 2 спутника.
Нам нужен класс Вселенной. Создадим файл Universe.java, и поместим в него следующий код:
import java.util.LinkedList;
public class Universe{
private String name;
private LinkedList<Planet> planets; //Список планет, которые есть в нашей вселенной
//Constructor
public Universe(String name){
this.name = name; // Дадим имя нашей вселенной. Просто что бы показать, как давать аргументы конструктору и куда их потом помещать
this.planets = new LinkedList<Planet>();//инициализация списка, он пока пуст
}
//Add planet
public void addPlanet(Planet p){
planets.add(p); //добавляем планету, переданную в аргументе, в наш список
}
//Переопределим метод toString, который возвращает объект типа String
//Это для того, что бы можно было красиво вывести информацию о вселенной в консоль
@ Override
public String toString(){
String res = "Universe "+name+": "
for(Planet p: planets){
//пробегаем по списку планет и добавляем их к нашему выводу
res+=p.toString()+", "; //так прибавлять одну строку к другой нельзя, это медленно и плохо, но для начало сойдет
}
return res; //возвращаем полученный результат.
}
}
Стоп стоп стоп! У нас же ведь только одна вселенная может существовать (мы же все таки не совсем боги)! Тут мы прибегаем к так называемому Singelton Pattern. Суть его в том, что мы создаем только один объект какого-то класса, и при каждом запросе возвращаем его. (Вообще вот сборище некоторых паттернов, очень занимательное и нужное чтиво). Примерно так его надо реализовывать:
import java.util.LinkedList;
public class Universe{
private String name;
private LinkedList<Planet> planets; //Список планет, которые есть в нашей вселенной
private static Universe instance = null; //Единственный объект этого класса, который и будет возвращен всем жаждующим
//Метод, который теперь будет вызываться, если нам понвдобится вселенная. Возвращает единственны существующий объект класса. Статичный.
public Universe getInstanceOf(){
if(instance==null)
instance=new Universe("My Universe");
return instance;
}
//Constructor
//Заметили? Конструктор стал private!
private Universe(String name){
this.name = name; // Дадим имя нашей вселенной. Просто что бы показать, как давать аргументы конструктору и куда их потом помещать
this.planets = new LinkedList<Planet>();//инициализация списка, он пока пуст
}
//Add planet
public void addPlanet(Planet p){
planets.add(p); //добавляем планету, переданную в аргументе, в наш список
}
//Переопределим метод toString, который возвращает объект типа String
//Это для того, что бы можно было красиво вывести информацию о вселенной в консоль
@ Override
public String toString(){
String res = "Universe "+name+": "
for(Planet p: planets){
//пробегаем по списку планет и добавляем их к нашему выводу
res+=p.toString()+", "; //так прибавлять одну строку к другой нельзя, это медленно и плохо, но для начало сойдет
}
return res; //возвращаем полученный результат.
}
}
Вот. Со вселенной закончили. Дальше нам нужны планеты. Также создадим файл Planet.java
import java.util.LinkedList;
public class Planet{
protected int radius;//Радиус планеты, protected потому что будет доступен подклассам
protected int orbitDistance;//Радиус орбиты
protected String name; //Название планеты
private LinkedList<Satellite> satellites;//список спутников планеты
public Planet(String name, int radius, int orbitDistance){
this.radius=radius;
this.orbitDistance=orbitDistance;
this.name=name;
satellites=new LinkedList<Satellite>();
}
public void addSatellite(Satellite s){
satellites.add(s);
}
@ Override
public String toString(){
String res="Planet "+name+", radius="+radius+", orbit distance="+orbitDistance;
}
}
И еще нам нужны спутники. Спутники будут подклассами планет, что бы показать, как работает наследование. Файл: Satelite.java:
//Extends значит что это подкласс планет. И все protected поля в Planet доступны и тут.
public class Satellite extends Planet{
public Satellite(String name, int radius, int orbitDistance){
super(name, radius, orbitDistance);//Просто вызываем конструктор класса Planet, который запихивает нужные значения в нужные переменные
}
//Переопределим метод toString. без этого переопределения будет вызван toString из класса Planet
@ Override
public String toString(){
return "Satellite "+super.toString(); //некрасивый вывод, зато видно, как можно использовать методы супер-классов. Здесь мы вызываем метод toString из класса Planet, и к строке, которую он возвращает, добавляем Satellite
}
}
С классами закончили. Осталось написать main, и запустить!
Итак, метод main поместим в класс Application. Файл Application.java:
public class Application{
private Universe universe;
private Planet pandoraPlanet;
private Planet deadStarPlanet;
private Planet terraPlanet;
private Satellite luneSatellite;
private Satellite cookieSatellite;
private Satellite iHaveNoMoreAboutForNamesSatellite;
public void init(){
universe=Universe.getInstanceOf();
pandoraPlanet=new Planet("Pandora", 15, 200);
deadStarPlanet=new Planet("DeadStar", 40, 500);
terraPlanet=new Planer("Terra", 36, 475);
luneSatellite = new Satellite("Lune", 2, 24);
cookieSatellite = new Satellite("Cookie", 3, 28);
iHaveNoMoreIdeasAboutNamesSatellite = new Satellite("I have no more ideas about names", 1, 87);
}
public void run(){
deadStarPlanet.addSatellite(cookieSatellite);
terraPlanet.addSatellite(luneSatellite);
terraPlanet.addSatellite(iHaveNoMoreAboutForNamesSatellite);
universe.addPlanet(deadStarPlanet);
universe.addPlanet(terraPlanet);
universe.addPlanet(pandoraPlanet);
System.out.println(universe);
}
public static void main(String[] args){
Application app = new Application();
app.init();
app.run();
}
}
Компилируем:
javac *.java
И запускаем:
java Application
Вот и все! Первое приложение готово и запущено. А дальше… Только ваша фантазия. И гугл вам в помощь.
Автор: Mgrin