/*
内部类:
1.在类中定义的类我们称之为内部类,它是外部类的一个成员。
2.内部类可以直接访问外部类的成员,但是外部类不能直接的去调用外部类的成员、
其实内部类调用外部类的成员的时候.其实是使用到了:类名.this.变量名 来访问外部类的成员。
3.在内部类中的方法可以使用this引用调用这个方法的内部类对象.
*/
class Outer
{
String name = "张三";
public void run()
{
System.out.println("Outer is Running");
}
public void show()
{
System.out.println("My name is Outer");
System.out.println(new Inner().age);
}
class Inner
{
int age = 19;
public void run()
{
System.out.println("Inner is Running");
}
public void eat()
{
this.run(); //this.代表方法所调用的对象.它的对象是inner 所以输出的是inner
show(); //因为创建内部类的时候.外部类的对象已经创建了. 如果虚拟机在内部类中找不到.它会到外部类去找这个show()对象.
System.out.println(Outer.this.name); //其实同等于:Outer.this.name //类名.name
System.out.println("Nnner is Eat");
}
}
}
class Demo
{
public static void main(String[] args)
{
Outer.Inner inner = new Outer().new Inner(); //类型要一致!
inner.run();
inner.eat();
}
}
/*
可以在方法中定义内部类?
System.out.println(age);为什么会访问不了呢.编译出错/
其实:当我们在外部类调用A对象的时候.run()方法由于age是存储在栈内存的临时变量中的. 当我们对象调用完毕过后呢.
有可能是会被释放调的.而当你再次调用的时候 age 的时候呢.由于虚拟机可能会被释放.所以调用不了.
那么:虚拟机认为你这样做是编译错误的!
*/
class A
{
String name = "小细" ;
public void run()
{
int age = 19;
class B
{
public void run()
{
String name = "王五";
System.out.println("my name is B");
//System.out.println(age);
System.out.println(A.this.name); //通过类名.this.属性名访问外部类的属性.
}
}
new B().run();
}
}
class Demo
{
public static void main(String[] args)
{
A a = new A();
a.run();
}
}
/*
匿名内部类:
*/
class Fruit
{
public void qupi()
{
}
}
class Person
{
public void eat(Fruit f)
{
f.qupi();
System.out.println("吃完啦!!");
}
}
class Demo
{
public static void main(String[] args)
{
Person p = new Person();
p.eat(new Fruit(){
public void qupi()
{
System.out.println("Apple把皮弄开!");
}
}
);
}
}
/*
static修饰的静态内部类:
1.静态的内部类可以声明非静态的属性和方法. 但是静态的内部类是不能访问外部类非静态的方法.因为外部类的属性需要创建对象才能调用.
你内部类是不需要创建对象的.所以调用不了。
2.静态的内部类不能访问非静态的属性.
*/
class Outer
{
static String name = "kudy";
String ID = "888";
static class Inner
{
int age = 19;
public void run()
{
System.out.println(age);
System.out.println("Inner is happy");
System.out.println(Outer.name); //因为是不需要创建对象的.所以可以使用Outer.name访问外部的静态的方法。
// System.out.println(Outer.ID);
}
}
}
class Demo
{
public static void main(String[] args)
{
Outer.Inner inner = new Outer.Inner(); //静态的内部类一定要静态的去创建!
//System.out.println(inner.age);
inner.run();
}
}
/*
类的继承
1.使用extends关键字来声明类的关系
2.子类会自动继承父类的属性与方法
*/
class Person
{
String name ;
public void run()
{
System.out.println("Person is Running");
}
}
class Man extends Person
{
public void toLike()
{
System.out.println(name +"运动"); //默认会添加上this的
}
}
class Demo
{
public static void main(String[] args)
{
Man man = new Man();
man.name = "小细";
man.run();
man.toLike();
}
}
/*
类的继承是为了实现代码的复用性,如果有多个类具有相同的方法.我们应该尽量把她抽出一个类来
*/
class Person
{
String name ;
int age;
public void eat()
{
System.out.println(name+"吃饭"+",年龄为:"+age); //this.name this.age
}
public void run()
{
System.out.println("需要运动");
}
}
class Student extends Person
{
public void eat()
{
System.out.println("吃一口饭");
super.eat(); //调用父类的方法、。
System.out.println("看一下作业");
}
}
class Teacher extends Person
{
public void eat()
{
System.out.println("抽一根");
super.eat();
System.out.println("再来一根");
}
}
class Demo
{
public static void main(String[] args)
{
Student student = new Student();
student.name = "小细";
student.age = 19;
student.eat();
student.run();
}
}
/*
父类型的引用指向子类型的对象.也就是想上类型转换.不需要强制转换
强制转换的要求: 父类型的引用指向子类型的对象。
3.把父类当做子类来使用是不行的,因为子类有的.父类型不一定有
4.当做子类当做父类来用时,只能使用父类型所拥有的方法。
如果调用子类拥有的方法.编译器会报错!所以需要强制转换.但在强制转换的前提下我们要知道父类型的引用是否是指向了子类型的对象
强制转换之前需要判断一下.
注意:
1.当你父类型的引用指向子类型的对象的时候.你必须要清楚的就是:你访问的属性是会是父类的.而不是子类的.
因为java在属性方法是做了静态的绑定.谁是我的类型.我就去谁的类型去找.而方法就刚好相反.
方法就是:谁指向谁.我就调用谁的方法.。 因为是做了动态的绑定。
*/
class Typist
{
String name = "小细";
public void type()
{
System.out.println("typeing");
}
}
class Coder extends Typist
{
String name = "王五";
public void type()
{
System.out.println("tepeing slowly!!!");
}
public void code()
{
System.out.println("Codeing");
}
}
class Demo
{
public static void main(String[] args)
{
//向上类型转换: 父类型的引用指向子类型的对象.
Typist typist = new Coder();
//typist.type(); 因为你是指向了子类型的引用.所以java做了动态绑定.也就是说你绑定了一个子类型的方法。
System.out.println(typist.name);
/*
为什么输出小细呢.因为java在检查的时候.属性是不做动态绑定的.也就是说.类型是谁.他就会找类型里面的属性.
*/
/*
Code code = new Typist();
子类型的引用不能指向父类的对象.因为子类有的.父类型不一定有.
*/
Coder coder;
if(typist instanceof Coder) //父类型的引用指向子类型的对象才可以抢走转换!
{
coder = (Coder)typist; //强制转换成子类
System.out.println(coder.name);
}
}
}
/*
因为java的属性在父类型的引用指向子类型的情况是做了静态的绑定的.所以我们可以这么做!
*/
class Person
{
private String name = "无名氏";
public String getName()
{
return name;
}
public void eat()
{
System.out.println("eating");
}
}
class A extends Person
{
private String name = "小细";
public String getName()
{
return name;
}
}
class B extends Person
{
String name = "kudy";
}
class Demo
{
public static void main(String[] args)
{
Person p = new A();
/*
因为java的父类型的引用指向子类型的对象的时候.方法使用了动态.而属性只使用了静态.也就是说:类型是那个.属性就是从
那里去找
*/
System.out.println(p.getName());//这样就是调用了子类型的属性啦~~
}
}
/*
什么情况下使用子类当做父类来使用
匿名内部类:new一个父类对象,后面跟一个花括号,这时不需要创建父类的实例
*/
class Person
{
String name = "无名氏";
public void eat()
{
//每个人的爱好不同!
}
}
class Restaurant
{
public void run(Person p)
{
p.eat();
}
}
class Chinese extends Person
{
public void eat()
{
String name = "中国人"; //在方法里面是动态调用的哦。
System.out.println(name+"我是拿筷子吃的!");
}
}
class American extends Person
{
public void eat()
{
String name = "美国人";
System.out.println(name+"我只吃汉堡包!");
}
}
class Demo
{
public static void main(String[] args)
{
Restaurant r = new Restaurant();
//r.run(new American());
r.run(new Chinese());
/*
内部类:
class JB extends Person
{
public void eat()
{
System.out.println("我是吃垃圾的!");
}
}
r.run(new JB());
*/
r.run(getIndia());
}
static Person getIndia()
{
String name = "印度菜";
Person p = new Person(){ //我创建了一个子类.子类里面有eat方法重写啦.之后呢.再把这个重写好的对象返回来.也就是说:父类型的引用指向子类型的对象
public void eat()
{
System.out.println(this.name+"印度菜");
}
};
return p;
}
}
class A
{
String name = "小三";
public String getName()
{
return name;
}
public void run()
{
System.out.println(name);
}
}
class B extends A
{
private String name = "小四";
public String getName()
{
return name;
}
public void run()
{
System.out.println(name);
}
public void show()
{
System.out.println("我是子类!");
}
}
class Demo
{
public static void main(String[] args)
{
A a = new B(); //父类型的引用指向子类型的对象. 就可以使用子类型与父类型所共同拥有的方法.但是子类出来的就不行。
// a.show();
/*
System.out.println(a.name);
如果这样写出来是小三,而不是小四,但是在方法里面输出来的就是小四.因为她的属性在方法里面运行啦.所以是动态的.
而你单独如果想输出它的属性的话,它是根据了静态绑定来进行操作.也就是输出了类型里面属性的内容!
那方法就是: 给所有的变量私有化.给他开一个public方法.返回属性!!因为方法是可以转换为动态的.
有的人可能会问?不相同可以吗? 如果不相同的话.前面已经说过: 就是子类型所特有的.你父类型是不可以调用.除非需要强制转换!
*/
String name = a.getName(); //这时候方法已经给重写
System.out.println(name); //输出的会是小四
}
}
/*
对象的比较:
对象的比较不能使用 == 这样比较的是比较地址. 应该用equals方法
因为所有的类都是默认的继承与Object! 我们可以重写它里面的equals比较方法。
*/
class Person
{
private String name ;
private int age ;
public Person(String name ,int age)
{
this.name = name ;
this.age = age ;
}
@Override //告诉编译器我重写父类型的方法! 大写的O
//重写父类的方法!
public boolean equals(Object obj)
{
if(this == obj)
return true;
if(obj instanceof Person) //如果你父类型的引用是指向了子类型的对象的.那么就判断.
{
//因为是按照了父类型的引用是指向了子类型的对象.首先我们要判断一下.强制类型转换.要不然我们是调用不了子类型的内容
Person p =(Person)obj;
if(this.name.equals(p.name)&&this.age == age)
return true;
}
return false;
}
}
class Demo
{
public static void main(String[] args)
{
Person p1 = new Person("张三",19); //p1就是当前对象!
Person p2 = new Person("张三",19);
System.out.println(p1.equals(p2));
}
}
class Person
{
String name ;
public void eat()
{
}
}
class Restaurant
{
public void show(Person p)
{
p.eat();
}
}
class Chinese extends Person
{
String name = "中国人";
public void eat()
{
System.out.println(name+"我吃中国菜!");
}
}
class Test
{
public static void main(String[] args)
{
Restaurant r = new Restaurant();
r.show(new Chinese());
/*
匿名内部类的第一种用法!
*/
r.show(new Person(){
public void eat()
{
System.out.println("日本人吃日本菜!");
}
}
);
r.show(getUSA());
}
public static Person getUSA()
{
Person p = new Person(){
public void eat()
{
String name = "美国人";
System.out.println(name+"吃美国菜!");
}
};
return p;
}
}
posted on 2012-08-07 00:56
、小细 阅读(64)
评论(0) 编辑 收藏