您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
javase第二季学习笔记-内部类
发布时间:2017-07-10 14:36:25编辑:雪饮阅读()
内部类就是在一个类的内部定义的类
成员内部类格式如下:
class Outer{
class Inner{}
}
编译上述代码会产生两个文件
Outer.class和Outer$Inner.class
示例:
public class NewKeywordDemo
{
public static void main(String[] args){}
}
class Dog
{
private String name;
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
//内部类(成员内部类)
class ChildDog
{
public void talk(){
System.out.println("我是子类的talk方法,父类的name属性是:"+name);
}
}
}
在外部创建内部类对象
内部类除了可以在外部中产生实例化对象,也可以在外部类的外部来实例化。
那么,根据内部类生成的*.class文件:Outer$Inner.class
“$”符号在程序运行时将替换为“.”
所以内部类的访问:通过”外部类.内部类”的形式表示.
Outer out=new Outer();//产生外部类实例
Outer.Inner in=null;//声明内部类对象
in=out.new Inner();//实例化内部类对象
通过外部类的外部来实例化示例:
public class NewKeywordDemo
{
public static void main(String[] args){
//声明名实例化外部类
Dog d=new Dog("小白");
d.say();
Dog.ChildDog cd=null;//声明内部类(也可以声明的同时直接实例化)
cd=d.new ChildDog();//创建内部类的实例
cd.talk();
}
}
class Dog
{
private String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
//内部类(成员内部类)
class ChildDog
{
public void talk(){
System.out.println("我是子类的talk方法,父类的name属性是:"+name);
}
}
}
在外部类中实例化内部类示例:
public class NewKeywordDemo
{
public static void main(String[] args){
//声明名实例化外部类
Dog d=new Dog("小白");
d.say();
d.childTalk();
}
}
class Dog
{
private String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
//内部类(成员内部类)
class ChildDog
{
public void talk(){
System.out.println("我是子类的talk方法,父类的name属性是:"+name);
}
}
//从外部类实例化内部类
public void childTalk(){
ChildDog child=new ChildDog();
child.talk();
}
}
方法内部类
内部类可以作为一个类的成员外,还可以把类放在方法内定义。
格式如下:
class Outer{
public void doSomething(){
class Inner{
public void seeOuter(){}
}
}
}
注意:
方法内部类只能在定义该内部类的方法内实例化。不可以在此方法外对其实例化。
方法内部类对象不能使用该内部类所在方法的非final局部变量(也就是说只能使用final修饰的局部变量。),该所在方法所接收的参数也是不能使用的。只有用final修饰的或者是父类的属性才可以。
我觉得这个应该算是经典面试题目吧,我百度了半天,大都有"局部变量的生命周期可能没有对象的长",对于这种回答我刚开始不理解,我心想的是这个方法中内部类实例化后必有一个变量接收这个实例化的引用。而此时该接收的变量是局部变量,肯定会在方法执行完毕就销毁。此时的确对象引用不在了,对象也就挂了。所以不影响什么。
但是刚才有提到"对象生命周期可能大于局部变量",关键就是这个"可能",而对于这个"可能",据说情况有好几种,我在百度去找到了其中一种解释。
就是说这个对象未必仅仅只是让其引用给一个局部变量,而且有可能把这个局部变量return(此时局部变量有引用),然后在main方法中某些语法就接收到这个return,然后通过这个return调用其内部的属性,那么问题来了,此时那个属性由于是之前那个方法的某个局部变量(此时早销毁了)
示例代码:
public class NewKeywordDemo
{
public static void main(String[] args){
//声明名实例化外部类
Dog d=new Dog("小白");
d.say();
d.childTalk();
}
}
class Dog
{
private String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
//从外部类实例化内部类
public void childTalk(){
class ChildDog
{
public void talk(){
System.out.println("我是方法内部类的talk方法,name属性是:"+name);
}
}
ChildDog child=new ChildDog();
child.talk();
}
}
静态内部类:
在一个类内部定义一个静态内部类:
静态的含义是该内部类可以像其它静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。
class Outer{
static class Inner{}
}
class Test{
public static void main(String[] args){
Outer.Inner n=new Outer.Inner();
}
}
如果类在方法内部,则只需要修饰其所在方法为静态方法即可,无需修饰该内部类
静态内部类只能访问静态属性或方法
如果内部类不想被从外部类的外部实例化,可以通过private修饰,private如果修饰类,也只能修饰内部类
public class NewKeywordDemo
{
public static void main(String[] args){
//静态内部类的实例化
Dog.ChildDog child=new Dog.ChildDog();
child.talk();
}
}
class Dog
{
private String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
//静态内部类
static class ChildDog
{
public void talk(){
System.out.println("我是静态内部类的talk方法");
}
}
}
匿名内部类:
匿名内部类的三种情况:
(1) 继承式的匿名内部类
(2) 接口式的匿名内部类
(3) 参数式的匿名内部类
(1)继承式匿名内部类实例代码:
public class NewKeywordDemo
{
public static void main(String[] args){
//继承式匿名内部类
Dog dog=new Dog("小白"){
public void say(){
System.out.println("我是继承式匿名内部类,name属性为:"+name);
}
};
dog.say();
}
}
class Dog
{
String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
}
(2)接口式匿名内部类实例代码:
public class NewKeywordDemo
{
public static void main(String[] args){
//接口式匿名内部类
Child child=new Child(){
public void talk(){
System.out.println("我是接口式匿名内部类的talk方法");
}
};
child.talk();
}
}
class Dog
{
String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
}
interface Child
{
public void talk();
}
(3)参数式匿名内部类实例:
public class NewKeywordDemo
{
public static void main(String[] args){
//参数式匿名内部类
childTalk(new Child(){
public void talk(){
System.out.println("我是参数式匿名内部类的talk方法");
}
});
}
public static void childTalk(Child c){
c.talk();
}
}
class Dog
{
String name;
public Dog(String name){
this.name=name;
}
public void say(){
System.out.println("我是父类的say方法,name属性是:"+name);
}
}
interface Child
{
public void talk();
}
在使用匿名内部类时,要记住以下几个原则:
(1)不能有构造方法,只能有个一个实例。
(2)不能定义任何静态成员,静态方法
(3)类头(new关键字后面)不能用public,protected,private,static修饰,当然在类体中对属性和方法还是可以修饰的。
(4)一定是在new后面,用其隐含实现一个接口或实现一个类
(5)匿名内部类为局部,所以局部内部类的所有限制都对其生效。(这里说的是变量的作用域。)
每个内部类都能独立的继承自一个(接口的)实现,所以无论外部类是否已经继承某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计和编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变的完整。接口解决了部分问题,而内部类有效的实现了“多重继承”。
关键字词:javase,内部类