Журнал LinuxFormat - перейти на главную

LXF84:Java

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Отмена правки № 71 участника OWeRQ (обсуждение))
м (восстановление кавычек в коде AWB)
 
(не показаны 5 промежуточных версий 3 участников)
Строка 1: Строка 1:
== Сказка Java ==
+
{{Цикл/Java}}
 +
=== Сказка Java ===
 
''ЧАСТЬ 1: От кофеварок до промышленных серверов и биллинговых систем - Java можно встретить буквально везде. Начните изучение этой технологии вместе с '''Антоном Черноусовым'''.''
 
''ЧАСТЬ 1: От кофеварок до промышленных серверов и биллинговых систем - Java можно встретить буквально везде. Начните изучение этой технологии вместе с '''Антоном Черноусовым'''.''
  
Строка 8: Строка 9:
 
Сегодня еще нельзя сказать, какая технология станет доминирующей, и, возможно, от вас зависит скорость распространения современной кроссплатформенной технологии создания приложений J2EE и языка программирования Java.
 
Сегодня еще нельзя сказать, какая технология станет доминирующей, и, возможно, от вас зависит скорость распространения современной кроссплатформенной технологии создания приложений J2EE и языка программирования Java.
  
Предложенные вашему вниманию уроки позволят овладеть основными понятиями ООЯ Java и создавать различные приложения с его помощью. Рассмотрев основы языка, мы сможем изучить типовые решения (паттерны) в программировании и приступить к изучению J2EE.
+
Предложенные вашему вниманию уроки позволят овладеть основными понятиями Java и создавать различные приложения с его помощью. Рассмотрев основы языка, мы сможем изучить типовые решения (паттерны) в программировании и приступить к изучению J2EE.
 
В первом уроке мы создадим свое первое приложение и разберемся с основными понятиями: инкапсуляция, наследование и полиморфизм. Для выполнения этого урока нам понадобится пакет Java SDK 1.5, текстовый редактор и немного терпения.
 
В первом уроке мы создадим свое первое приложение и разберемся с основными понятиями: инкапсуляция, наследование и полиморфизм. Для выполнения этого урока нам понадобится пакет Java SDK 1.5, текстовый редактор и немного терпения.
 
=== Героический объект ===
 
=== Героический объект ===
Приступая к этой серии материалов, я вспомнил, что, как правило, изучение языков программирования начинается с написания приложения «Hello World!», но такой прием настолько изъезжен, что я намереваюсь предложить пример поинтереснее: мы напишем приложение, рассказывающее сказку. Основа приложения – два класса. Каждый класс содержит члены двух видов: атрибуты и методы. Атрибуты – это данные, принадлежащие самому классу. Совокупное значение атрибутов определяет состояние объекта или класса. Метод – это последовательность операторов, изменяющих значения атрибутов и, как следствие, состояние класса или объекта.
+
Приступая к этой серии материалов, я вспомнил, что, как правило, изучение языков программирования начинается с написания приложения "Hello World!", но такой прием настолько изъезжен, что я намереваюсь предложить пример поинтереснее: мы напишем приложение, рассказывающее сказку. Основа приложения – два класса. Каждый класс содержит члены двух видов: атрибуты и методы. Атрибуты – это данные, принадлежащие самому классу. Совокупное значение атрибутов определяет состояние объекта или класса. Метод – это последовательность операторов, изменяющих значения атрибутов и, как следствие, состояние класса или объекта.
  
 
В каждой интересной сказке должен быть свой герой. Предлагаю взглянуть на класс, который реализует нашего героя. Итак, по порядку. Следующий код необходимо сохранить в файл '''FirstHero.java.'''
 
В каждой интересной сказке должен быть свой герой. Предлагаю взглянуть на класс, который реализует нашего героя. Итак, по порядку. Следующий код необходимо сохранить в файл '''FirstHero.java.'''
<code>
+
<source lang = "java">
public class FirstHero {
+
public class FirstHero {
  private String quest;
+
  private String quest;
  public FirstHero(String Quest) {
+
  public FirstHero(String Quest) {
    this.quest = Quest;
+
    this.quest = Quest;
  }
+
  }
  public void setQuest(String Quest){
+
  public void setQuest(String Quest){
    this.quest = Quest;
+
    this.quest = Quest;
  };
+
  };
  public String getQuest(){
+
  public String getQuest(){
    return quest;
+
    return quest;
  };
+
  };
}
+
}
</code>
+
</source>
 
Расположение одного класса в одном файле считается хорошим тоном среди программистов на Java – так что приучайтесь к нему сразу. Имя файла должно совпадать с названием класса, расширение у файла – '''.java.'''
 
Расположение одного класса в одном файле считается хорошим тоном среди программистов на Java – так что приучайтесь к нему сразу. Имя файла должно совпадать с названием класса, расширение у файла – '''.java.'''
  
Строка 33: Строка 34:
  
 
Вы можете заметить, что первый метод (третья строка представленного ранее листинга) имеет то же название, что и класс – FirstHero. Такой метод называется конструктором. Конструктор – это метод, который используется при создании экземпляра класса для задания внутреннего состояния объекта, например:
 
Вы можете заметить, что первый метод (третья строка представленного ранее листинга) имеет то же название, что и класс – FirstHero. Такой метод называется конструктором. Конструктор – это метод, который используется при создании экземпляра класса для задания внутреннего состояния объекта, например:
<code>
+
<source lang = "java">
FirstHero ourNewHero = new FirstHero(“Спасти царевну”);
+
FirstHero ourNewHero = new FirstHero("Спасти царевну");
</code>
+
</source>
 
Единственный атрибут нашего класса quest имеет тип строка (String). Для установки значения атрибута quest используется метод
 
Единственный атрибут нашего класса quest имеет тип строка (String). Для установки значения атрибута quest используется метод
 
setQuest. Метод setQuest является public и не возвращает никакого значения. Для обозначения методов, не возвращающих значение, используется зарезервированное слово void. Для вызова метода setQuest необходим обязательный параметр: Quest типа String. Для получения значения атрибута quest используется метод getQuest, который вызывается без параметров, является открытым и возвращает значение типа String.
 
setQuest. Метод setQuest является public и не возвращает никакого значения. Для обозначения методов, не возвращающих значение, используется зарезервированное слово void. Для вызова метода setQuest необходим обязательный параметр: Quest типа String. Для получения значения атрибута quest используется метод getQuest, который вызывается без параметров, является открытым и возвращает значение типа String.
  
 
Вызов описанных выше методов для объекта ourNewHero осуществляется следующим образом:
 
Вызов описанных выше методов для объекта ourNewHero осуществляется следующим образом:
<code>
+
<source lang = "java">
ourNewHero.getQuest();
+
ourNewHero.getQuest();
ourNewHero.setQuest(“какая-то строка”);
+
ourNewHero.setQuest("какая-то строка");
</code>
+
</source>
 
Парные методы, различающиеся приставками set и get, принято создавать для работы с закрытыми атрибутами. Это обязательное
 
Парные методы, различающиеся приставками set и get, принято создавать для работы с закрытыми атрибутами. Это обязательное
 
условие для реализации объекта в виде JavaBean. Что такое JavaBean, мы обсудим позже – сейчас запомните, что такое наименование методов позволяет избавиться от ряда проблем в больших системах.
 
условие для реализации объекта в виде JavaBean. Что такое JavaBean, мы обсудим позже – сейчас запомните, что такое наименование методов позволяет избавиться от ряда проблем в больших системах.
Строка 49: Строка 50:
 
Приступим к написанию самой сказки. Возьмите следующий код и поместите его в файл '''Story.java'''.
 
Приступим к написанию самой сказки. Возьмите следующий код и поместите его в файл '''Story.java'''.
  
<code>
+
<source lang = "java">
public class Story {
+
public class Story {
  public static void main(String[] args) {
+
  public static void main(String[] args) {
    FirstHero ourNewHero = new FirstHero(“Спасти царевну );
+
    FirstHero ourNewHero = new FirstHero("Спасти царевну ");
    System.out.println(“Наш герой хочет отправиться в путь и + ourNewHero.getQuest());
+
    System.out.println("Наш герой хочет отправиться в путь и " + ourNewHero.getQuest());
  }
+
  }
}
+
}
</code>
+
</source>
  
 
Это класс Story, он имеет всего один метод main, который является статичным (static-методы и переменные принято называть переменными класса и методами класса, т.к. они общие для всех объектов) и используется для работы с классом в целом. Метод main – это стартовая точка для запуска программы, с которой начинается интерпретация кода.
 
Это класс Story, он имеет всего один метод main, который является статичным (static-методы и переменные принято называть переменными класса и методами класса, т.к. они общие для всех объектов) и используется для работы с классом в целом. Метод main – это стартовая точка для запуска программы, с которой начинается интерпретация кода.
Строка 63: Строка 64:
  
 
Откомпилируем код и увидим, что у нас получилось. Для компиляции переместитесь в каталог, где вы разместили свои файлы и выполните следующую команду:
 
Откомпилируем код и увидим, что у нас получилось. Для компиляции переместитесь в каталог, где вы разместили свои файлы и выполните следующую команду:
<code>
+
<source lang = "java">
# javac *.java
+
# javac *.java
</code>
+
</source>
 
При желании вы можете откомпилировать классы по отдельности, следующим образом:
 
При желании вы можете откомпилировать классы по отдельности, следующим образом:
<code>
+
<source lang = "java">
# javac Story.java
+
# javac Story.java
# javac FirstHero.java
+
# javac FirstHero.java
</code>
+
</source>
 
В итоге вы получите два файла '''Story.class''' и '''FirstHero.class'''. Теперь посмотрим на результат:
 
В итоге вы получите два файла '''Story.class''' и '''FirstHero.class'''. Теперь посмотрим на результат:
<code>
+
<source lang = "java">
# java Story
+
# java Story
Наш герой хочет отправиться в квест и Спасти царевну
+
Наш герой хочет отправиться в квест и Спасти царевну
</code>
+
</source>
  
 
Первая программа на Java готова и работает! Вы создали два класса и научились выводить информацию в консоль. Но мы забыли о
 
Первая программа на Java готова и работает! Вы создали два класса и научились выводить информацию в консоль. Но мы забыли о
Строка 85: Строка 86:
 
*Комментарии JavaDoc – это многострочные комментарии, заключенные между /** и */, например:
 
*Комментарии JavaDoc – это многострочные комментарии, заключенные между /** и */, например:
  
<code>
+
<source lang = "java">
/**
+
/**
  * Класс является прототипом объекта “герой”
+
* Класс является прототипом объекта "герой"
  * @author Chernousov Anton
+
* @author Chernousov Anton
  * @version 0.1
+
* @version 0.1
  */
+
*/
public class FirstHero {
+
public class FirstHero {
+
/**
+
/**
    * Метод предназначен для установки внутренней переменной
+
  * Метод предназначен для установки внутренней переменной
quest
+
quest
    * в значение Quest.
+
  * в значение Quest.
    * У этого метода один параметр
+
  * У этого метода один параметр
    * @param Quest это переменная означает задание для Героя
+
  * @param Quest это переменная означает задание для Героя
    */
+
  */
  public void setQuest(String Quest)
+
  public void setQuest(String Quest)
+
</code>
+
</source>
  
 
Комментарии JavaDoc предназначены для формирования документации к проекту из исходных кодов. Если добавить в файл '''FirstHero.java''' только что приведенные строки, то с помощью команды '''javadoc -author -version *.java''' можно сформировать документацию к нашему проекту.
 
Комментарии JavaDoc предназначены для формирования документации к проекту из исходных кодов. Если добавить в файл '''FirstHero.java''' только что приведенные строки, то с помощью команды '''javadoc -author -version *.java''' можно сформировать документацию к нашему проекту.
Строка 111: Строка 112:
  
 
Наследование – это одна из парадигм программирования, которая связана с инкапсуляцией. Суть наследования заключается в следующем: если есть класс, инкапсулирующий в себе некоторые атрибуты и методы, то класс, наследующий его, автоматически наследует все его атрибуты и методы.
 
Наследование – это одна из парадигм программирования, которая связана с инкапсуляцией. Суть наследования заключается в следующем: если есть класс, инкапсулирующий в себе некоторые атрибуты и методы, то класс, наследующий его, автоматически наследует все его атрибуты и методы.
<code>
+
<source lang = "java">
public class SecondHero extends FirstHero{
+
public class SecondHero extends FirstHero{
  public SecondHero(String Quest) {
+
  public SecondHero(String Quest) {
    super(Quest + “ Несмеяну”);
+
    super(Quest + " Несмеяну");
  }
+
  }
}
+
}
</code>
+
</source>
 
Расположенный выше код объявляет класс SecondHero, который с помощью зарезервированного слова extends наследует (расширяет) класс FirstHero. В Java класс может наследовать (расширять)только один класс. При наследовании класса FirstHero, содержащего
 
Расположенный выше код объявляет класс SecondHero, который с помощью зарезервированного слова extends наследует (расширяет) класс FirstHero. В Java класс может наследовать (расширять)только один класс. При наследовании класса FirstHero, содержащего
конструктор, обязательно требуется переопределить его (например, как это делается в методе SecondHero). При выполнении оператора super(Quest) будет вызван аналогичный метод из суперкласса (класс-родителя). Строкой super(Quest + “Несмеяну”) мы переопределяем поведение конструктора. Естественно, класс SecondHero может содержать новые атрибуты и методы.
+
конструктор, обязательно требуется переопределить его (например, как это делается в методе SecondHero). При выполнении оператора super(Quest) будет вызван аналогичный метод из суперкласса (класс-родителя). Строкой super(Quest + "Несмеяну") мы переопределяем поведение конструктора. Естественно, класс SecondHero может содержать новые атрибуты и методы.
  
 
Для проверки механизма наследования сохраните приведенный текст класса SecondHero в файл '''SecondHero.java''' и в файле '''Story.java''' измените имя класса FirstHero на SecondHero. Откомпилируйте и запустите программу, в результате вы должны увидеть следующее:
 
Для проверки механизма наследования сохраните приведенный текст класса SecondHero в файл '''SecondHero.java''' и в файле '''Story.java''' измените имя класса FirstHero на SecondHero. Откомпилируйте и запустите программу, в результате вы должны увидеть следующее:
<code>
+
<source lang = "java">
# java Story
+
# java Story
Наш герой хочет отправиться в путь и Спасти царевну Несмеяну
+
Наш герой хочет отправиться в путь и Спасти царевну Несмеяну
</code>
+
</source>
 
При разработке программы, перед тем, как приступить к программированию, сначала проводится процесс проектирования (например, через UML-нотации). В результате проектирования появляется документация к проекту, а также спецификации классов. Интерфейс – это явно указанная спецификация набора методов, которые должны быть представлены в классе, реализующий эту спецификацию. В серьезном проекте на момент начала программирования перед программистом оказываются интерфейсы, которые он должен реализовать в классах.
 
При разработке программы, перед тем, как приступить к программированию, сначала проводится процесс проектирования (например, через UML-нотации). В результате проектирования появляется документация к проекту, а также спецификации классов. Интерфейс – это явно указанная спецификация набора методов, которые должны быть представлены в классе, реализующий эту спецификацию. В серьезном проекте на момент начала программирования перед программистом оказываются интерфейсы, которые он должен реализовать в классах.
  
 
Интерфейс в Java – это специальный класс, в котором отсутствует реализация! Давайте напишем интерфейс для нашего класса FirstHero. Следует скопировать следующий далее код и поместить его в файл '''Hero.java''' – именно этот интерфейс мы будет использован далее. Как вы видите, в отличие от других классов, интерфейс объявляется с помощью зарезервированного слова interface. В нашем случае интерфейс представляет собой следующий набор методов:
 
Интерфейс в Java – это специальный класс, в котором отсутствует реализация! Давайте напишем интерфейс для нашего класса FirstHero. Следует скопировать следующий далее код и поместить его в файл '''Hero.java''' – именно этот интерфейс мы будет использован далее. Как вы видите, в отличие от других классов, интерфейс объявляется с помощью зарезервированного слова interface. В нашем случае интерфейс представляет собой следующий набор методов:
<code>
+
<source lang = "java">
public interface Hero {
+
public interface Hero {
  public void setQuest(String Quest);
+
  public void setQuest(String Quest);
  public String getQuest();
+
  public String getQuest();
}
+
}
</code>
+
</source>
 
Чтобы класс FirstHero реализовывал интерфейс Hero, необходимо изменить первую строчку в файле '''FirstHero.java''' на public class FirstHero implements Hero {. Интерфейс может наследовать (расширять) множество других интерфейсов. Наример:
 
Чтобы класс FirstHero реализовывал интерфейс Hero, необходимо изменить первую строчку в файле '''FirstHero.java''' на public class FirstHero implements Hero {. Интерфейс может наследовать (расширять) множество других интерфейсов. Наример:
<code>
+
<source lang = "java">
public interface Lord {
+
public interface Lord {
  public String sendToQuest();
+
  public String sendToQuest();
  public void setBodyguard(Hero hisHero);
+
  public void setBodyguard(Hero hisHero);
  public Hero getBodyguard();
+
  public Hero getBodyguard();
}
+
}
 
   
 
   
public interface King extends Hero, Lord{
+
public interface King extends Hero, Lord{
  public void setWife (String PrincesName);
+
  public void setWife (String PrincesName);
  public String getWife();
+
  public String getWife();
}
+
}
</code>
+
</source>
 
Класс может одновременно наследовать класс и реализовывать один или несколько интерфейсов. Например, как в классе LandLord,
 
Класс может одновременно наследовать класс и реализовывать один или несколько интерфейсов. Например, как в классе LandLord,
 
который наследует класс FirstHero и реализует интерфейс Lord:
 
который наследует класс FirstHero и реализует интерфейс Lord:
<code>
+
<source lang = "java">
public class LandLord extends FirstHero implements Lord{
+
public class LandLord extends FirstHero implements Lord{
  private Hero bodyguard;
+
  private Hero bodyguard;
  public LandLord(String Quest, Hero hisHero) {
+
  public LandLord(String Quest, Hero hisHero) {
    super(Quest);
+
    super(Quest);
    this.bodyguard = hisHero;
+
    this.bodyguard = hisHero;
  }
+
  }
  public String sendToQuest() {
+
  public String sendToQuest() {
    bodyguard.setQuest(this.getQuest());
+
    bodyguard.setQuest(this.getQuest());
    return null;
+
    return null;
  }
+
  }
  public void setBodyguard(Hero hisHero) {
+
  public void setBodyguard(Hero hisHero) {
    this.bodyguard = hisHero;
+
    this.bodyguard = hisHero;
  }
+
  }
  public Hero getBodyguard() {
+
  public Hero getBodyguard() {
    return bodyguard;
+
    return bodyguard;
  }
+
  }
}
+
}
</code>
+
</source>
 
Чтобы окончательно закрыть тему наследования, необходимо поговорить про абстрактные классы – те, что занимают промежуточное
 
Чтобы окончательно закрыть тему наследования, необходимо поговорить про абстрактные классы – те, что занимают промежуточное
 
место между интерфейсами и реальными классами. Объявление абстрактного класса или метода выполняется с помощью специального
 
место между интерфейсами и реальными классами. Объявление абстрактного класса или метода выполняется с помощью специального
 
слова abstract:
 
слова abstract:
<code>
+
<source lang = "java">
abstract public class Knight
+
abstract public class Knight
</code>
+
</source>
 
Абстрактный класс представляет собой неполную реализацию всех объявленных методов, и его можно наследовать, как и любой из классов. Обязательным условием при наследовании является полная реализация абстрактных методов.
 
Абстрактный класс представляет собой неполную реализацию всех объявленных методов, и его можно наследовать, как и любой из классов. Обязательным условием при наследовании является полная реализация абстрактных методов.
  
Строка 182: Строка 183:
 
=== Перегруженные методы ===
 
=== Перегруженные методы ===
 
Иногда при создании сложных (и не очень) систем есть необходимость реализовать два различных метода, названых одинаково – это возможно с помощью перегруженных (overloading) методов. Выбор реализации зависит от типа объектов, переданных в качестве параметров.
 
Иногда при создании сложных (и не очень) систем есть необходимость реализовать два различных метода, названых одинаково – это возможно с помощью перегруженных (overloading) методов. Выбор реализации зависит от типа объектов, переданных в качестве параметров.
<code>
+
<source lang = "java">
public class GreatKing extends LandLord implements King{
+
public class GreatKing extends LandLord implements King{
  private String wife;
+
  private String wife;
  private boolean theftedWife;
+
  private boolean theftedWife;
+
 
  public GreatKing(String Quest, Hero hisHero) {
+
  public GreatKing(String Quest, Hero hisHero) {
    super(Quest, hisHero);
+
    super(Quest, hisHero);
  }
+
  }
+
 
  public void setWife(String PrincesName) {
+
  public void setWife(String PrincesName) {
    this.wife = PrincesName;
+
    this.wife = PrincesName;
    this.theftedWife = false;
+
    this.theftedWife = false;
  }
+
  }
+
 
  public String getWife() {
+
  public String getWife() {
    if (theftedWife){return null;}
+
    if (theftedWife){return null;}
    else{ return wife;}
+
    else{ return wife;}
  }
+
  }
+
 
  public String getWife(boolean flag) {
+
  public String getWife(boolean flag) {
    if (flag){ this.theftedWife = true;}
+
    if (flag){ this.theftedWife = true;}
    return wife;
+
    return wife;
  }
+
  }
}
+
}
</code>
+
</source>
 
В представленном классе GreatKing существуют две реализации перезагруженного метода getWife, которые можно вызвать следующим образом:
 
В представленном классе GreatKing существуют две реализации перезагруженного метода getWife, которые можно вызвать следующим образом:
<code>
+
<source lang = "java">
GreatKing ourKing = new GreatKing(“Править мудро”, (Hero) new FirstHero(“Охранять господина”));
+
GreatKing ourKing = new GreatKing("Править мудро", (Hero) new FirstHero("Охранять господина"));
String hisWife = ourKing.getWife();
+
String hisWife = ourKing.getWife();
String theftedHisWife = ourKing.getWife(true);
+
String theftedHisWife = ourKing.getWife(true);
</code>
+
</source>
  
 
=== Вместо заключения ===
 
=== Вместо заключения ===
 
Ну вот, мы создали всех героев. Разместите интерфейсы Lord, King, а также классы LandLord и GreatKing в соответствующих файлах.
 
Ну вот, мы создали всех героев. Разместите интерфейсы Lord, King, а также классы LandLord и GreatKing в соответствующих файлах.
 
Немного измените класс Story, чтобы завершить сказку:
 
Немного измените класс Story, чтобы завершить сказку:
<code>
+
<source lang = "java">
public class Story {
+
public class Story {
  public static void main(String[] args) {
+
  public static void main(String[] args) {
    // создадим наших героев
+
    // создадим наших героев
    Hero ourNewHero = (Hero) new FirstHero(“Спасити царевну”);
+
    Hero ourNewHero = (Hero) new FirstHero("Спасити царевну");
    GreatKing ourKing = new GreatKing(“Править мудро”, (Hero) new FirstHero(“Охранять господина”));
+
    GreatKing ourKing = new GreatKing("Править мудро", (Hero) new FirstHero("Охранять господина"));
    LandLord ourNewLandLord = new LandLord(“Похитить царевну”, (Hero) new FirstHero(“Охранять господина”));
+
    LandLord ourNewLandLord = new LandLord("Похитить царевну", (Hero) new FirstHero("Охранять господина"));
    // Женим нашего короля
+
    // Женим нашего короля
    ourKing.setWife(“Несмеяна”);
+
    ourKing.setWife("Несмеяна");
    // И начнем повествование
+
    // И начнем повествование
    System.out.println(“Жил был мудрый король, и должен был он + ourKing.getQuest());
+
    System.out.println("Жил был мудрый король, и должен был он " + ourKing.getQuest());
    System.out.println(“Была у него жена, и звали ее + ourKing.getWife());
+
    System.out.println("Была у него жена, и звали ее " + ourKing.getWife());
    System.out.println(“Был в королевстве коварный Визирь и хотел он + ourNewLandLord.getQuest());
+
    System.out.println("Был в королевстве коварный Визирь и хотел он " + ourNewLandLord.getQuest());
    System.out.println(“И сделал это”);
+
    System.out.println(сделал это");
    String wife = ourKing.getWife(true);
+
    String wife = ourKing.getWife(true);
    //
+
    //
    System.out.println(“А наш герой жаждал + ourNewHero.getQuest() + ..и добился этого”);
+
    System.out.println(наш герой жаждал " + ourNewHero.getQuest() + " ..и добился этого");
    ourKing.setWife(wife);
+
    ourKing.setWife(wife);
    System.out.println(“Король был счастлив.);
+
    System.out.println("Король был счастлив.");
    System.out.println(“Ну а что случилось дальше вы можете придумать сами...);
+
    System.out.println("Ну а что случилось дальше вы можете придумать сами...");
  }
+
  }
}
+
}
</code>
+
</source>
 
Откомпилируйте и насладитесь результатом выполнения урока.
 
Откомпилируйте и насладитесь результатом выполнения урока.
  
В следующей статье мы поговорим о простых числах и других типах, вычислениях, циклах, массивах и списках.
+
В [[LXF85:Java|следующей статье]] мы поговорим о простых числах и других типах, вычислениях, циклах, массивах и списках.

Текущая версия на 16:55, 27 апреля 2008

Содержание

[править] Сказка Java

ЧАСТЬ 1: От кофеварок до промышленных серверов и биллинговых систем - Java можно встретить буквально везде. Начните изучение этой технологии вместе с Антоном Черноусовым.

Начиная ряд статей о программировании на объектно-ориентированном языке Java, хотел бы выразить свое мнение относительно корпоративного рынка разработки программного обеспечения, на котором в данный момент борются за лидерство два гиганта, две платформы: J2EE и .NET.

В основе платформы J2EE лежит язык программирования Java – приложения, созданные с его помощью, являются кроссплатформенными, сам язык, средства разработки и технология активно поддерживаются многими корпорациями: Sun, Google, IBM, Oracle, BEA. Платформа пользуется большой популярностью и среди компаний, ориентированных на OpenSource, таких как Apache Foundation. В противовес J2EE, корпорация Microsoft предлагает свою технологию .NET, которая является колоссом, построенным на мощи программного обеспечения Microsoft.

Сегодня еще нельзя сказать, какая технология станет доминирующей, и, возможно, от вас зависит скорость распространения современной кроссплатформенной технологии создания приложений J2EE и языка программирования Java.

Предложенные вашему вниманию уроки позволят овладеть основными понятиями Java и создавать различные приложения с его помощью. Рассмотрев основы языка, мы сможем изучить типовые решения (паттерны) в программировании и приступить к изучению J2EE. В первом уроке мы создадим свое первое приложение и разберемся с основными понятиями: инкапсуляция, наследование и полиморфизм. Для выполнения этого урока нам понадобится пакет Java SDK 1.5, текстовый редактор и немного терпения.

[править] Героический объект

Приступая к этой серии материалов, я вспомнил, что, как правило, изучение языков программирования начинается с написания приложения "Hello World!", но такой прием настолько изъезжен, что я намереваюсь предложить пример поинтереснее: мы напишем приложение, рассказывающее сказку. Основа приложения – два класса. Каждый класс содержит члены двух видов: атрибуты и методы. Атрибуты – это данные, принадлежащие самому классу. Совокупное значение атрибутов определяет состояние объекта или класса. Метод – это последовательность операторов, изменяющих значения атрибутов и, как следствие, состояние класса или объекта.

В каждой интересной сказке должен быть свой герой. Предлагаю взглянуть на класс, который реализует нашего героя. Итак, по порядку. Следующий код необходимо сохранить в файл FirstHero.java.

public class FirstHero {
  private String quest;
  public FirstHero(String Quest) {
    this.quest = Quest;
  }
  public void setQuest(String Quest){
    this.quest = Quest;
  };
  public String getQuest(){
    return quest;
  };
}

Расположение одного класса в одном файле считается хорошим тоном среди программистов на Java – так что приучайтесь к нему сразу. Имя файла должно совпадать с названием класса, расширение у файла – .java.

Первый созданный нами класс содержит один защищенный атрибут (private – модификатор, зарезервированное слово, которое обеспечивает возможность обращения к члену класса только внутри класса) и три открытых метода (public – модификатор, зарезервированное слово, которое обеспечивает возможность обращения к члену класса из любого другого класса.). Хорошо спроектированный класс не имеет открытых атрибутов, что позволяет быть уверенным в правильной работе с ними. Доступ к защищенным атрибутам осуществляется через открытые методы. Такая организация класса позволяет разработчику через методы реализовать различные проверки и исключить неправильное поведение объекта. Класс представляет собой объединение атрибутов и методов в единое целое – подобное объединение называется инкапсуляцией.

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

FirstHero ourNewHero = new FirstHero("Спасти царевну");

Единственный атрибут нашего класса quest имеет тип строка (String). Для установки значения атрибута quest используется метод setQuest. Метод setQuest является public и не возвращает никакого значения. Для обозначения методов, не возвращающих значение, используется зарезервированное слово void. Для вызова метода setQuest необходим обязательный параметр: Quest типа String. Для получения значения атрибута quest используется метод getQuest, который вызывается без параметров, является открытым и возвращает значение типа String.

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

ourNewHero.getQuest();
ourNewHero.setQuest("какая-то строка");

Парные методы, различающиеся приставками set и get, принято создавать для работы с закрытыми атрибутами. Это обязательное условие для реализации объекта в виде JavaBean. Что такое JavaBean, мы обсудим позже – сейчас запомните, что такое наименование методов позволяет избавиться от ряда проблем в больших системах.

Приступим к написанию самой сказки. Возьмите следующий код и поместите его в файл Story.java.

public class Story {
  public static void main(String[] args) {
    FirstHero ourNewHero = new FirstHero("Спасти царевну ");
    System.out.println("Наш герой хочет отправиться в путь и " + ourNewHero.getQuest());
  }
}

Это класс Story, он имеет всего один метод main, который является статичным (static-методы и переменные принято называть переменными класса и методами класса, т.к. они общие для всех объектов) и используется для работы с классом в целом. Метод main – это стартовая точка для запуска программы, с которой начинается интерпретация кода.

В ходе интерпретации метода main создается новый объект ourNewHero, а также вызывается метод println объекта out, который обеспечивает вывод в стандартный выходной поток строковойпеременной.

Откомпилируем код и увидим, что у нас получилось. Для компиляции переместитесь в каталог, где вы разместили свои файлы и выполните следующую команду:

# javac *.java

При желании вы можете откомпилировать классы по отдельности, следующим образом:

# javac Story.java
# javac FirstHero.java

В итоге вы получите два файла Story.class и FirstHero.class. Теперь посмотрим на результат:

# java Story
Наш герой хочет отправиться в квест и Спасти царевну

Первая программа на Java готова и работает! Вы создали два класса и научились выводить информацию в консоль. Но мы забыли о комментариях...

Комментарии бывают нескольких типов:

  • Строчные начинаются с символа // и длятся до окончания строки.
  • Многострочные комментарии заключаются между /* и */.
  • Комментарии JavaDoc – это многострочные комментарии, заключенные между /** и */, например:
/**
 * Класс является прототипом объекта "герой"
 * @author Chernousov Anton
 * @version 0.1
 */
public class FirstHero {/**
   * Метод предназначен для установки внутренней переменной
quest
   * в значение Quest.
   * У этого метода один параметр
   * @param Quest это переменная означает задание для Героя
   */
  public void setQuest(String Quest)

Комментарии JavaDoc предназначены для формирования документации к проекту из исходных кодов. Если добавить в файл FirstHero.java только что приведенные строки, то с помощью команды javadoc -author -version *.java можно сформировать документацию к нашему проекту.

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

[править] Наследование, интерфейсы и их реализация

Наша сказка написана, но что делать, если проект большой и над ним работает много людей? Как реализовать одновременное программирование разных классов так, чтобы результаты, полученные отдельными разработчиками, можно было без труда соединить в единое целое? Для решения этой задачи, а также задачи множественного наследования в Java существуют интерфейсы – interface. Но обо всем по порядку.

Наследование – это одна из парадигм программирования, которая связана с инкапсуляцией. Суть наследования заключается в следующем: если есть класс, инкапсулирующий в себе некоторые атрибуты и методы, то класс, наследующий его, автоматически наследует все его атрибуты и методы.

public class SecondHero extends FirstHero{
  public SecondHero(String Quest) {
    super(Quest + " Несмеяну");
  }
}

Расположенный выше код объявляет класс SecondHero, который с помощью зарезервированного слова extends наследует (расширяет) класс FirstHero. В Java класс может наследовать (расширять)только один класс. При наследовании класса FirstHero, содержащего конструктор, обязательно требуется переопределить его (например, как это делается в методе SecondHero). При выполнении оператора super(Quest) будет вызван аналогичный метод из суперкласса (класс-родителя). Строкой super(Quest + "Несмеяну") мы переопределяем поведение конструктора. Естественно, класс SecondHero может содержать новые атрибуты и методы.

Для проверки механизма наследования сохраните приведенный текст класса SecondHero в файл SecondHero.java и в файле Story.java измените имя класса FirstHero на SecondHero. Откомпилируйте и запустите программу, в результате вы должны увидеть следующее:

# java Story
Наш герой хочет отправиться в путь и Спасти царевну Несмеяну

При разработке программы, перед тем, как приступить к программированию, сначала проводится процесс проектирования (например, через UML-нотации). В результате проектирования появляется документация к проекту, а также спецификации классов. Интерфейс – это явно указанная спецификация набора методов, которые должны быть представлены в классе, реализующий эту спецификацию. В серьезном проекте на момент начала программирования перед программистом оказываются интерфейсы, которые он должен реализовать в классах.

Интерфейс в Java – это специальный класс, в котором отсутствует реализация! Давайте напишем интерфейс для нашего класса FirstHero. Следует скопировать следующий далее код и поместить его в файл Hero.java – именно этот интерфейс мы будет использован далее. Как вы видите, в отличие от других классов, интерфейс объявляется с помощью зарезервированного слова interface. В нашем случае интерфейс представляет собой следующий набор методов:

public interface Hero {
  public void setQuest(String Quest);
  public String getQuest();
}

Чтобы класс FirstHero реализовывал интерфейс Hero, необходимо изменить первую строчку в файле FirstHero.java на public class FirstHero implements Hero {. Интерфейс может наследовать (расширять) множество других интерфейсов. Наример:

public interface Lord {
  public String sendToQuest();
  public void setBodyguard(Hero hisHero);
  public Hero getBodyguard();
}
 
public interface King extends Hero, Lord{
  public void setWife (String PrincesName);
  public String getWife();
}

Класс может одновременно наследовать класс и реализовывать один или несколько интерфейсов. Например, как в классе LandLord, который наследует класс FirstHero и реализует интерфейс Lord:

public class LandLord extends FirstHero implements Lord{
  private Hero bodyguard;
  public LandLord(String Quest, Hero hisHero) {
    super(Quest);
    this.bodyguard = hisHero;
  }
  public String sendToQuest() {
    bodyguard.setQuest(this.getQuest());
    return null;
  }
  public void setBodyguard(Hero hisHero) {
    this.bodyguard = hisHero;
  }
  public Hero getBodyguard() {
    return bodyguard;
  }
}

Чтобы окончательно закрыть тему наследования, необходимо поговорить про абстрактные классы – те, что занимают промежуточное место между интерфейсами и реальными классами. Объявление абстрактного класса или метода выполняется с помощью специального слова abstract:

abstract public class Knight

Абстрактный класс представляет собой неполную реализацию всех объявленных методов, и его можно наследовать, как и любой из классов. Обязательным условием при наследовании является полная реализация абстрактных методов.

[править] Полиморфизм

Полиморфизм – это концепция, реализованная в Java, которая позволяет одному и тому же объекту выступать в разных формах. Например, экземпляр класс LandLord можно использовать как объект класса FirstHero. Это стало возможным благодаря тому, что класс LandLord наследует класса FirstHero.

[править] Перегруженные методы

Иногда при создании сложных (и не очень) систем есть необходимость реализовать два различных метода, названых одинаково – это возможно с помощью перегруженных (overloading) методов. Выбор реализации зависит от типа объектов, переданных в качестве параметров.

public class GreatKing extends LandLord implements King{
  private String wife;
  private boolean theftedWife;
 
  public GreatKing(String Quest, Hero hisHero) {
    super(Quest, hisHero);
  }
 
  public void setWife(String PrincesName) {
    this.wife = PrincesName;
    this.theftedWife = false;
  }
 
  public String getWife() {
    if (theftedWife){return null;}
    else{ return wife;}
  }
 
  public String getWife(boolean flag) {
    if (flag){ this.theftedWife = true;}
    return wife;
  }
}

В представленном классе GreatKing существуют две реализации перезагруженного метода getWife, которые можно вызвать следующим образом:

GreatKing ourKing = new GreatKing("Править мудро", (Hero) new FirstHero("Охранять господина"));
String hisWife = ourKing.getWife();
String theftedHisWife = ourKing.getWife(true);

[править] Вместо заключения

Ну вот, мы создали всех героев. Разместите интерфейсы Lord, King, а также классы LandLord и GreatKing в соответствующих файлах. Немного измените класс Story, чтобы завершить сказку:

public class Story {
  public static void main(String[] args) {
    // создадим наших героев
    Hero ourNewHero = (Hero) new FirstHero("Спасити царевну");
    GreatKing ourKing = new GreatKing("Править мудро", (Hero) new FirstHero("Охранять господина"));
    LandLord ourNewLandLord = new LandLord("Похитить царевну", (Hero) new FirstHero("Охранять господина"));
    // Женим нашего короля
    ourKing.setWife("Несмеяна");
    // И начнем повествование
    System.out.println("Жил был мудрый король, и должен был он " + ourKing.getQuest());
    System.out.println("Была у него жена, и звали ее " + ourKing.getWife());
    System.out.println("Был в королевстве коварный Визирь и хотел он " + ourNewLandLord.getQuest());
    System.out.println("И сделал это");
    String wife = ourKing.getWife(true);
    //
    System.out.println("А наш герой жаждал " + ourNewHero.getQuest() + " ..и добился этого");
    ourKing.setWife(wife);
    System.out.println("Король был счастлив.");
    System.out.println("Ну а что случилось дальше вы можете придумать сами...");
  }
}

Откомпилируйте и насладитесь результатом выполнения урока.

В следующей статье мы поговорим о простых числах и других типах, вычислениях, циклах, массивах и списках.

Персональные инструменты
купить
подписаться
Яндекс.Метрика