Existe um princípio interessante sobre o qual muitos já ouviram falar. Chama-se "Dividir e Conquistar". Este princípio é utilizado em muitas áreas da vida humana, por exemplo, na política. Denota a divisão de um grande número de partes heterogêneas do estado, incitando e utilizando a hostilidade entre essas partes. Em outras palavras: criar conflito entre aqueles que potencialmente representam uma ameaça ao poder. Mas somos programadores, por isso estamos interessados apenas na interpretação técnica deste princípio. E é assim: “O princípio de “Dividir para Conquistar” é dividir um problema grande em problemas menores até que se tornem elementares. Então você precisa resolvê-los sequencialmente e combinar tudo em um sistema completo. Este programa deve resolver o problema determinado” Ou seja, você simplesmente divide um problema grande em problemas menores, que não são um problema para você resolver. E então você reúne a solução em uma grande solução. Para seguir este princípio simples e útil, a programação Java usa métodos. Por exemplo, estamos criando um robô boxeador. É importante para nós que ele se mova bem, dê golpes certeiros e também observe o inimigo em busca de pontos fracos. Seria estranho escrever tudo isso em um método principal , não seria? Se descrevermos tudo em um método, será algo assim:
метод main() {
// Описание действий шага вперед
подача напряжения в отдельные модули;
поднятие ноги;
перевод в другую точку;
поставить ногу;
перенести вес на другую ногу;
если (противникАтакует()) {
// Описание действий уклонения робота.
...
} еслиНет {
// Описание действий обманного атакующего удара.
...
}
// Описание действий шага назад
...
}
E se precisarmos dar um passo à frente ou dar um chute em outra parte do programa? Descreva todas as ações novamente? Não cabe. Existem muitas linhas repetidas nas quais é fácil se perder. Precisamos colocar a descrição dos detalhes da ação em um módulo separado, que realizará a etapa do robô. E podemos chamar o método em uma linha. Algo assim:
метод шагВперед() {
// Описание действий шага вперед
подача напряжения в отдельные модули;
поднятие ноги;
перевод в другую точку;
поставить ногу;
перенести вес на другую ногу;
}
метод уклонение() {
// Действия для уклонения
...
}
метод обманныйАтакующийУдар() {
// Действия для удара
...
}
метод шагНазад() {
// Действия для шага назад
...
}
метод противникАтакует() {
// Робот проверяет атакует ли противник
}
метод main() {
шагВперед();
если (противникАтакует()) {
уклонение();
} еслиНет {
обманныйАтакующийУдар();
}
шагНазад();
}
Agora separamos a funcionalidade do robô, bem como um método main() compacto e claro . O restante dos métodos também pode ser dividido em qualquer funcionalidade, por exemplo, deceptiveAttackingStrike pode ser dividido em métodos deceptiveMovement , Leg Movement , attack . E eles, por sua vez, são atribuídos a tarefas mais simples para, em última análise, obter um conjunto de tarefas elementares. Ok, agora vamos escrever tudo lindamente em um formato que Java aceite.
public static void stepForward() {
// Многострочный code, описывающий
// действия робота для выполнения шага
System.out.println("The robot takes a step forward");
}
public static void evasion() {
// Действия для уклонения
System.out.println("Robot shy of impact");
}
public static void deceptiveAttackBlow() {
// Действия для удара
System.out.println("The robot performs a deceptive strike");
}
public static void stepBack() {
// Действия для шага назад
System.out.println("The robot takes a step backwards");
}
public static void main(String[] args) {
stepForward();
if (isEnemyAttacked()) {
evasion();
} else {
deceptiveAttackBlow();
}
stepBack();
}
public static boolean isEnemyAttacked() {
// Метод проверяет, атакует ли враг. returns логическое meaning.
return true;
}
Entendo que este código pode não estar um pouco claro para você agora, especialmente algumas palavras como void , return e assim por diante. Não se apresse em jogar tomates, vou explicar tudo agora. A ideia geral do paradigma “Dividir para Conquistar” deve estar clara para você. Os métodos nos ajudarão nisso. A estrutura geral das declarações de métodos é a seguinte:
модификатор_доступа возвращаемое_meaning Name_метода(принимаемые_параметры) {
//Тело метода
}
Modificador de acesso
O modificador de acesso consiste em várias palavras-chave: public , private , package . Estas palavras indicam o escopo do método. Vou explicar de forma simples: com esta palavra você parece estar compartilhando uma guloseima saborosa com outras pessoas. Gostoso é o seu método. Se for private , você não compartilha o método com outras classes. Se package , você compartilha apenas com classes dentro do pacote (as classes são coletadas em pacotes específicos, você aprenderá isso mais tarde). Pois bem, o público mostra que você é a própria gentileza e compartilha uma delícia (método) com todo o programa. Algo assim. Depois de alguns níveis você entenderá muito melhor o papel dessas palavras.Valor de retorno
Veja o exemplo acima: todos os métodos são marcados com a palavra-chave void , exceto one -isEnemyAttacked , que retorna um valor booleano . Se um método estiver marcado como void , ele poderá não retornar nada. Este método simplesmente executa um conjunto de ações e pronto. Agora preste atenção ao método principal . Aqueles métodos que retornam void são chamados assim mesmo, no corpo do método. Mas o método isEnemyAttacked é chamado entre parênteses da instrução if . Por retornar um valor booleano, temos a oportunidade não de utilizar uma variável intermediária, mas de inseri-la diretamente. O retorno de um valor ocorre usando a palavra-chave return . Se um método retornar o tipo int , podemos chamar o método a partir de qualquer expressão:public static int getNumber() {
return 5;
}
public static void main(String[] args) {
int result = 5 + 6 + getNumber();
System.out.println(result);
}
Conclusão:
16
O método getNumber retorna um valor int , então podemos chamá-lo a partir de uma expressão. Além disso, o método pode retornar qualquer tipo, incluindo aqueles que você mesmo criou. Se você especificou um tipo de retorno para um método, deverá retornar algo. Você não pode escrever assim:
public static int findMaxNumber(int a, int b) {
if(a>b) {
return a;
}
}
O compilador irá repreendê-lo dizendo que quando a primeira condição for atendida, você retornará algo, mas quando a segunda condição for atendida, você não o fará.
Passando parâmetros
Você pode passar parâmetros para o método que são usados durante sua operação. O exemplo mais primitivo é a soma de dois números. Mas não somos primitivos, certo? Tomemos outro exemplo, bastante estereotipado. Digamos que temos um método chef() - cook. Podemos passar os ingredientes da sopa para este método no bloco de parâmetros e, como resultado, este método nos retorna a sopa. Assim:public static void main(String[] args) {
String[] ingredients;
// Инициализация массива ингредиентов
Soup soup = chef(ingredients);
}
public static Soup chef(String[] ingredients) {
Soup soup = new Soup();
// Процесс варки супа
return soup;
}
(Digamos que temos uma classe Soup pré-criada ) No método principal, criamos um array de ingredientes e depois “damos ao chef” (passamos para o método chef ). “O cozinheiro faz a sopa” e depois nos devolve como objeto da classe Sopa . Tudo é muito simples. Você pode passar quaisquer parâmetros, tipos primitivos, objetos, arrays e assim por diante para o método.
Passando parâmetros por referência e por valor
Na linguagem de programação Java, quaisquer parâmetros são passados para um método pelo seu valor. Contudo, este mecanismo é diferente para tipos primitivos e para objetos. Se você passar qualquer tipo primitivo para um método e alterá-lo, ele não será alterado no método principal. Você simplesmente passou uma cópia do valor e a variável original foi preservada. O exemplo mais simples:public static void main(String[] args) {
int x = 1;
System.out.println(x);
getNumber(x);
System.out.println(x);
}
public static void getNumber(int i) {
i = i + 100;
}
Conclusão:
onze
Porém, no caso de objetos, as alterações afetam o objeto original:
public class Program
{
public static void main(String[] args) {
WiseMan wiseMan = new WiseMan();
wiseMan.setIq(300);
System.out.println(wiseMan);
changeObject(wiseMan);
System.out.println(wiseMan);
}
public static void changeObject(WiseMan m) {
m.setIq(100);
}
}
public class WiseMan {
int iq;
public void setIq(int iq) {
this.iq = iq;
}
public int getIq() {
return iq;
}
public String toString() {
return "Our wise man has an IQ "+iq;
}
}
Conclusão:
Nosso sábio tem IR 300 Nosso sábio tem IR 100
Temos uma classe WiseMan que possui uma propriedade iq . E dois métodos que controlam o valor deste campo. No método principal, criamos um objeto wiseMan , definimos o valor iq como 300 . Então passamos nosso sábio com iq 300 para o método changeObject , mas neste método ele se torna estúpido. Definimos o valor de iq como 100. Depois, no método principal, imprimimos o objeto. Você pode ver que no método changeObject estamos manipulando outro sábio na variável m . No entanto, estamos modificando nosso objeto original. O fato é que o objeto wiseMan no método principal e o objeto m no método changeObject são o mesmo homem sábio, e uma referência ao objeto é copiada no método como parâmetro. Tenha isso em mente ao editar um objeto em métodos individuais.
Finalmente, algumas palavras sobre o modificador estático
Em geral, algumas palavras não bastam aqui, mas vou tentar. Os métodos regulares não marcados com este modificador pertencem ao objeto de classe. E os métodos estáticos pertencem à própria classe. Métodos regulares podem ser usados em objetos individuais. Veja a classe WiseMan do exemplo acima. Cada sábio terá seus próprios métodos getIq e setIq , porque o nível de QI de cada pessoa é diferente. Se adicionarmos um método estático generateAWisePhrase a esta classe , poderemos chamar esse método sem um objeto:WiseMan.generateAWisePhrase();
Em geral, esta informação é suficiente por enquanto, pois várias palestras podem ser escritas sobre static . Siga algumas regras ao escrever um método para manter a ordem no seu código:
- Dê nomes significativos aos seus métodos para que fique claro o que eles fazem.
- Tente não escrever métodos muito longos. O comprimento ideal é de 8 a 15 linhas.
- O número de parâmetros do método não deve exceder 4-5.
- Se você tiver funcionalidade semelhante duas vezes em seu código, pense: talvez valha a pena generalizá-la e colocá-la em um método separado?
GO TO FULL VERSION