Olá! Você já se perguntou por que o Java foi projetado dessa maneira? No sentido de que você cria classes, com base nelas - objetos, classes possuem métodos, etc. Mas por que a estrutura da linguagem é tal que os programas consistem em classes e objetos, e não em outra coisa? Por que o conceito de “objeto” foi inventado e colocado em primeiro plano? Todas as linguagens funcionam dessa maneira e, caso contrário, quais benefícios isso traz ao Java? Como você pode ver, há muitas perguntas :) Vamos tentar responder a cada uma delas na palestra de hoje.
Kristen Nygaard e Ole Johan Dahl - criadores de Simula
Parece que Simula é uma linguagem antiga para os padrões de programação, mas sua conexão de “família” com Java é visível a olho nu. Provavelmente, você pode ler facilmente o código escrito nele e explicar em termos gerais o que ele faz :)
Princípios OOP:
O que é programação orientada a objetos (OOP)
É claro que Java é composto de objetos e classes por uma razão. Isso não é um capricho de seus criadores, nem mesmo uma invenção deles. Existem muitas outras linguagens baseadas em objetos. A primeira linguagem desse tipo foi chamada Simula e foi inventada na década de 1960 na Noruega. Entre outras coisas, Simula introduziu os conceitos de “ classe ” e “ método ”.Begin
Class Rectangle (Width, Height); Real Width, Height;
Begin
Real Area, Perimeter;
Procedure Update;
Begin
Area := Width * Height;
OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
Perimeter := 2*(Width + Height);
OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
End of Update;
Update;
OutText("Rectangle created: "); OutFix(Width,2,6);
OutFix(Height,2,6); OutImage;
End of Rectangle;
Rectangle Class ColouredRectangle (Color); Text Color;
Begin
OutText("ColouredRectangle created, color = "); OutText(Color);
OutImage;
End of ColouredRectangle;
Ref(Rectangle) Cr;
Cr :- New ColouredRectangle(10, 20, "Green");
End;
O exemplo de código foi retirado do artigo Simula - 50 anos de OOP . Como você pode ver, Java e seu ancestral não são tão diferentes um do outro :) Isso se deve ao fato de que o surgimento do Simula marcou o nascimento de um novo conceito - a programação orientada a objetos. A Wikipedia fornece a seguinte definição de OOP: Programação orientada a objetos (OOP) é uma metodologia de programação baseada na representação de um programa como uma coleção de objetos, cada um dos quais é uma instância de uma classe específica, e as classes formam uma hierarquia de herança. É, na minha opinião, muito bem sucedido. Você começou recentemente a aprender Java, mas dificilmente há palavras nele que não lhe sejam familiares :) Hoje, OOP é a metodologia de programação mais comum. Além do Java, os princípios OOP são usados em muitas linguagens populares das quais você já deve ter ouvido falar. Estes são C++ (é usado ativamente por desenvolvedores de jogos de computador), Objective-C e Swift (eles escrevem programas para dispositivos Apple), Python (mais procurado em aprendizado de máquina), PHP (uma das linguagens de desenvolvimento web mais populares), JavaScript (mais simples, diga o que não fazem nele) e muitos outros. Na verdade, quais são esses “princípios” de OOP? Vamos contar com mais detalhes.
Princípios OOP
Este é o básico. 4 características principais que juntas formam o paradigma de programação orientada a objetos. Compreendê-los é a chave para se tornar um programador de sucesso.Princípio 1. Herança
A boa notícia é que você já está familiarizado com alguns dos princípios da OOP! :) Já encontramos herança algumas vezes em palestras e tivemos tempo para trabalhar com ela. Herança é um mecanismo que permite descrever uma nova classe com base em uma existente (pai). Nesse caso, as propriedades e funcionalidades da classe pai são emprestadas pela nova classe. Por que a herança é necessária e quais benefícios ela oferece? Em primeiro lugar, reutilização de código. Os campos e métodos descritos nas classes pai podem ser usados nas classes descendentes. Se todos os tipos de carros possuem 10 campos comuns e 5 métodos idênticos, basta colocá-los na classe paiAuto
. Você pode usá-los em classes descendentes sem problemas. Vantagens sólidas: tanto quantitativamente (menos código) quanto, como resultado, qualitativamente (as classes ficam muito mais simples). Ao mesmo tempo, o mecanismo de herança é muito flexível e você pode adicionar separadamente a funcionalidade ausente nos descendentes (alguns campos ou comportamento específico de uma classe específica). Em geral, como na vida cotidiana: somos todos semelhantes aos nossos pais em alguns aspectos, mas diferentes deles em alguns aspectos :)
Princípio 2. Abstração
Este é um princípio muito simples. Abstração significa destacar as características principais e mais significativas de um objeto e vice-versa - descartar as secundárias e insignificantes. Não vamos reinventar a roda e relembrar um exemplo de uma antiga palestra sobre aulas. Digamos que estamos criando um arquivo dos funcionários da empresa. Para criar objetos funcionários, escrevemos uma classeEmployee
. Quais características são importantes para sua descrição no arquivo da empresa? Nome completo, data de nascimento, número de segurança social, número de identificação fiscal. Mas é pouco provável que num cartão deste tipo precisemos da sua altura, cor dos olhos e do cabelo. A empresa não precisa dessas informações sobre o funcionário. Portanto, para a classe Employee
definiremos as variáveis String name
, int age
, int socialInsuranceNumber
e int taxNumber
, e abandonaremos informações que nos são desnecessárias, como a cor dos olhos, e as abstrairemos. Mas se criarmos um catálogo de modelos fotográficos para uma agência, a situação muda drasticamente. Para descrever um modelo, a altura, a cor dos olhos e do cabelo são muito importantes para nós, mas o número TIN não é necessário. Portanto, na classe Model
criamos variáveis String height
, String hair
, String eyes
.
Princípio 3: Encapsulamento
Já o encontramos. Encapsulamento em Java significa limitar o acesso aos dados e a capacidade de alterá-los. Como você pode ver, é baseado na palavra “cápsula”. Nesta “cápsula” escondemos alguns dados importantes para nós que não queremos que ninguém altere. Um exemplo simples da vida. Você tem um nome e um sobrenome. Todo mundo que você conhece os conhece. Mas eles não têm acesso para alterar seu nome e sobrenome. Esse processo, pode-se dizer, está “encapsulado” no escritório de passaportes: lá você só pode alterar seu nome e sobrenome, e só você pode fazer isso. Outros “usuários” têm acesso somente leitura ao seu nome e sobrenome :) Outro exemplo é o dinheiro do seu apartamento. Deixá-los à vista no meio da sala não é uma boa ideia. Qualquer “usuário” (pessoa que vier até sua casa) poderá alterar o número do seu dinheiro, ou seja, Pegue-os. É melhor encapsulá-los em um cofre. Somente você terá acesso e somente com um código especial. Exemplos óbvios de encapsulamento com os quais você já trabalhou são modificadores de acesso (private
, public
etc.) e getter-setters. Se o campo age
da classe Cat
não estiver encapsulado, qualquer um poderá escrever:
Cat.age = -1000;
E o mecanismo de encapsulamento nos permite proteger o campo age
com um método setter, no qual podemos verificar se a idade não pode ser um número negativo.
Princípio 4. Polimorfismo
Polimorfismo é a capacidade de tratar vários tipos como se fossem do mesmo tipo. Neste caso, o comportamento dos objetos será diferente dependendo do tipo a que pertencem. Parece um pouco complicado? Vamos descobrir agora. Vejamos o exemplo mais simples - animais. Vamos criar uma classeAnimal
com um único método - voice()
e dois de seus descendentes - Cat
e Dog
.
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Bow-wow!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
Agora vamos tentar criar um link Animal
e atribuir um objeto a ele Dog
.
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.voice();
}
}
Qual método você acha que será chamado? Animal.voice()
ou Dog.voice()
? O método da classe será chamado Dog
: Woof-woof! Criamos uma referência Animal
, mas o objeto se comporta como Dog
. Se necessário, ele pode se comportar como um gato, um cavalo ou outro animal. O principal é atribuir uma referência de tipo geral Animal
a um objeto de uma classe descendente específica. Isto é lógico, porque todos os cães são animais. Isso é o que quisemos dizer quando dissemos “os objetos se comportarão de maneira diferente dependendo do tipo que são”. Se criássemos um objeto Cat
-
public static void main(String[] args) {
Animal cat = new Cat();
cat.voice();
}
o método voice()
geraria "Meow!" O que significa “a capacidade de trabalhar com vários tipos como se fossem do mesmo tipo”? Isso também é bastante fácil. Imaginemos que estamos a criar um salão de cabeleireiro para animais. Nosso salão de cabeleireiro deve ter capacidade para cortar todos os animais, por isso vamos criar um método shear()
(“cortar”) com um parâmetro Animal
– o animal que vamos cortar.
public class AnimalBarbershop {
public void shear(Animal animal) {
System.out.println("The haircut is ready!");
}
}
E agora podemos passar shear
objetos Cat
e objetos para o método Dog
!
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
AnimalBarbershop barbershop = new AnimalBarbershop();
barbershop.shear(cat);
barbershop.shear(dog);
}
Aqui está um exemplo claro: a classe AnimalBarbershop
trabalha com tipos Cat
como Dog
se fossem do mesmo tipo. Ao mesmo tempo, eles têm um comportamento Cat
diferente Dog
: usam a voz de maneira diferente.
GO TO FULL VERSION