-
Notifications
You must be signed in to change notification settings - Fork 0
2.4 Create top level and nested classes
Lembretes:
- Uma non static inner class pode ter membros static, mas eles devem ser final;
- non static inner class pode utilizar qualquer modificador de acesso;
- non static inner class não pode ter métodos static;
- nested class dentro de métodos não podem ser declaradas static;
- Uma classe anonima é implicitamente final;
- Uma classe anonima pode ser declarada dentro de um método static;
O código abaixo não compila, no método public void doA() { inner1.doA(); }
o método apresentado na classe anônima não é acessível.
Lembre também que na criação da classe anônima é necessário finalizar com ;
public class TopClass {
public Inner inner1 = new Inner(){
public void doA(){ System.out.println("doing A"); }
};
public void doA() { inner1.doA(); }
}
class Inner {
int value;
}
Instanciando inner class:
public class TestClass{
public class A{}
public static class B {}
public static void main(String args[]){
class C{}
}
}
Opção valida:
new TestClass().new A();
A classe B é static inner class e não pode ser instanciada dessa maneira:
new TestClass().new B();
Maneira correta:
new TestClass.B()
Uma static inner class pode ter membros não static.
class TopClass {
static class Inner {
private String nome;
}
}
Lembretes:
- Uma inner class pode ser privada;
- Uma inner class pode herdar da outer class;
- Para acessar um atributo da outer class:
Onion.this.data
public class Onion {
private String data = "skin";
private class Layer extends Onion {
String data = "thegoodpart";
public String getData() {
return data;
}
public String getDataDoOnion() {
return Onion.this.data;
}
}
public String getData() {
return new Layer().getData();
}
public String getDataDoOnion() {
return new Layer().getDataDoOnion();
}
public static void main(String[] args) {
Onion o = new Onion();
System.out.println(o.getData()); // thegoodpart
System.out.println(o.getDataDoOnion()); // skin
}
}
Lembretes:
public class Teste2 {
private String strPrivada = "private";
protected String strProtegida = "protected";;
String strPadrao = "default";
public String strPublica = "public";;
// inner class
public class Inner{
private void teste() {
// Independente do modificador de acesso, os membros pode ser utilizado na inner class
System.out.println(strPrivada);
System.out.println(strProtegida);
System.out.println(strPadrao);
System.out.println(strPublica);
System.out.println(Teste2.this.strPrivada);
System.out.println(Teste2.this.strProtegida);
System.out.println(Teste2.this.strPadrao);
System.out.println(Teste2.this.strPublica);
}
}
// static inner class
public static class InnerStatic{
private void teste() {
// Os membros da outer class nao são static então nao compila
// System.out.println(strPrivada);
// System.out.println(strProtegida);
// System.out.println(strPadrao);
// System.out.println(strPublica);
//
// System.out.println(Teste2.this.strPrivada);
// System.out.println(Teste2.this.strProtegida);
// System.out.println(Teste2.this.strPadrao);
// System.out.println(Teste2.this.strPublica);
System.out.println("Teste");
}
}
public static void main(String[] args) {
//Para funcionar deve existir uma instancia de Teste2
// new Inner();
new Teste2().new Inner().teste();
new InnerStatic().teste();
new Teste2.InnerStatic().teste();
}
}
Lembre que nem sempre é possivel referencia um membro da outer class na inner class.
O exemplo abaixo é um deles: shodowing
public class Teste3 {
private String nome = "Eu sou Outer";;
class Inner extends Teste3 {
private String nome = "Eu sou Inner";
public String getNome() {
return nome;
}
public String getNomeOuter() {
return Teste3.this.nome;
}
}
public static void main(String[] args) {
System.out.println(new Teste3().new Inner().nome); //Eu sou Inner
System.out.println(new Teste3().nome); //Eu sou Outer
System.out.println(new Teste3().new Inner().getNomeOuter()); //Eu sou Outer
}
}
É possivel criar instancias diferentes com a mesma outer class.
public class Teste4 {
class Inner {}
public static void main(String[] args) {
Teste4 teste4 = new Teste4();
Inner inner1 = teste4.new Inner();
Inner inner2 = teste4.new Inner();
System.out.println("Estão apontandos para o mesmo objeto = " + (inner1 == inner2)); // false
}
}
Lembretes:
- Mesmo uma outer class sendo
final
ela pode ter inner class; - O no access modifier
static
não pode ser utilizado em top level class ou class que não é membro; - Classes declaradas dentro de metodos não podem ser
static
; - Classes anônimas não podem definir construtores explicitos;
Uma static inner class pode ter uma non - static inner class.
public class Teste6 {
// static inner class
public static class InnerStatic {
// inner class dentro de uma static inner class
class InnerInner {}
}
public static void main(String[] args) {
// instanciando uma classe que esta dentro da static inner class
new Teste6.InnerStatic().new InnerInner();
}
}
O codigo abaixo não compila. A inner class foi criada em um método static e não tem referencia ao objeto TestFrame.
public class TestFrame extends Frame {
String s = "Message";
public static void main(String args[]) {
TestFrame t = new TestFrame();
Button b = new Button("press me");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Message is " + s);
}
});
t.add(b);
}
}
Membro static em non static inner class não funciona, só se for final.
class Outer {
class Inner
{
static int k = 10; // com final compila
}
}
Se a classe tem um construtor a anonima pode utiliza-lo.
//outer class
class TestClass {
//construtor com parametro
public TestClass(int i) {}
//método de instancia
public void m1() {
//classe anonima utilizando o contrutor que tem um parametro
TestClass al = new TestClass(10) {
public void actionPerformed(ActionEvent e) {
}
};
}
}