黑马程序员-内部类
2014-06-06 18:19 黑马程序员* 阅读(141) 评论(0) 收藏 举报内部类的访问规则;
1.内部类可以访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式;外部类名.this
2.外部类要访问内部类,必须建立内部类的对象。
访问格式;
当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。
格式;
1.外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Out. Inner in = new Outer().new Inner();
2.当内部类在成员位置上,可以被成员修饰符所修饰。成员修饰符:private,public protected,default
比如,0.private;讲内部类在外部类中进行封装。
1.static ;内部类就具备static的特性。
当内部类内被static(关键字)修饰后,只能直接访问外部类中的static成员,否则出现访问局限。
2.在外部其他类中,如何直接访问static内部类的非静态成员呢?
;new Outer.Inner().function();
3.在外部其他类中,如何直接访问static内部类的静态成员呢?
;Outer.Inner.function();注意区别于上面,Inner后面没有了()
4.注意当内部类中定义了静态成员,该类必须是static的
5.当外部类中的静态方法访问内部类,内部类也必须是static的
class Out {
int x = 3;
class Inner {
int x = 4;
void function(){
int x =6 ;
System.out.println("inner"+x);//打印结果;6。内部有不出去找
如果想打印3呢,System.out.println("inner"+out.this.x);
//如果想打印4呢,System.out.println("inner"+this.x);函数参数或者函数中的局部变量和成员变量同名的情况下,成员变量被屏蔽,
//此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。只有成员前面才省略了this。
}
void method(){
Inner in = new Inner();//外部类的方法访问内部类,即外部类访问内部类
in.fountion();
}}
*/
//以下用于演示static
1.当内部类内被static修饰后,只能直接访问外部类中的static成员,静态先于对象存在。
class Outer{
private static int x = 3;//x是非静态变量
static class Inner{
void function(){
System.out.println("inner"+x); ^
}}}
2.在外部其他类中,如何直接访问static内部类的非静态成员呢?
class Outer{
static private int x = 3;//x 是静态变量
static class Inner {
void function() {
System.out.println("inner"+x);
}}}
class day09demo{
public static void main(String[] args){
new Outer.Inner().function();
//创建对象时,Out.Inner 是一个整体,new Outer.Inner()
程序怎么走的;Outer一加载,Inner直接加载,静态类不用建立对象,类名可以直接调用,
new Outer.Inner()建立内部类对象
function是非静态的,所以用内部类对象调用function方法
}}
3.注意当内部类中定义了静态成员(如方法),该类必须是static的,为什么
class Outer{
static private int x = 3;
static class Inner{
static void function(){
System.out.println("inner"+x);
}}}
什么时候定义内部类?
当描述事物时,事物1的内部还有事物2,该事物2用内部类表示。
那么事物2的对象就可以直接调用事物1的属性。如心脏放在人体内。
这时候内部类往往会私有。
练习:
interface Inter{
void method();
}
class Test {
/*
//补足代码。通过匿名内部类
static class Inner implements Inter {
public void method(){
System.out.println("hha");
}}
static Inter function(){
return new Inner();// 可以直接返回内部类对象。
}
*/
}
class day0903{
public static void main(String[] args){
Test.function().method();
/*Test.类名. 表明有一个静态的function函数
.method()表示前面是一个对象,而且返回值
是Inter(类)型的对象,但是Inter是没有对象的
所以必须是子类对象才可以
*/
}
}
//补足代码。通过匿名内部类
class Test {
/*static class Inner implements Inter{
public void method(){
System.out.println("hha");
}}
*/
static Inter function(){
return new Inter(){// Inner 消失变成匿名类
static class Inner implements Inter{
public void method(){
System.out.println("hha");
}
}
}.method;// 可以直接返回对象.方法吗,如果对象.方法的返回值void,则不就成了return 空,可以。
//public void show(){return;},返回为void,return可以不写,也可以后面什么都不写。
}}
/*
内部类定义在局部时,
1.不可以被成员修饰符修饰,如private,static
2.可以直接访问外部类中的成员,因为还持有外部类中的引用
*/
class outer{
int x = 3;
void method(final int y){
final int x=4;//
class Inner {
void function(){////此处function不可以用static,因为用了之后,Inner也要变成静态,但在局部位置内部类不可以是静态的。
System.out.println(outer.this.x );
}
}
new Inner().function();
}}
class day0904 {
public static void main(String[] args) {
// 外部其他类如果想要访问方法中的内部类,只能在方法体中创建对象,
// 该内部类不能在外部其他类中创建实例对象。因为随着类的加载静态方法会加载进
内存中,我们可以使用类名直接调用,但是如果内部类的方法是静态的,那么我们可以直接
用Outer.Inner.function()调用,但是因为加载时内部类还没有被加载,所以无法直接用
类名调用,违反的static的原则。
}}
问题:加载一个类时,其内部类是否同时被加载?
class test{
public static void main(String[] args){
Outer out = new Outer();
// Outer.Inner1 oi = new Outer.Inner1();
}}
class Outer{
static class Inner1{
static {
System.out.println("Static Inner");
}
}}
结论:
输出语句执行未执行。只有在调用到内部类时,内部类才会加载进内存。
这也同大多数类一样,只有在被调用时才会加载,保证jvm的执行效率。
也证明了为什么内部类定义静态方法,该内部类必须是静态的。静态先加载,
但是它所属的始终都没有被加载。
匿名内部类;
1.匿名内部类其实就是内部类的简写格式
2.定义匿名内部类的前提;
内部类必须是继承一个类或者实现借口。
3.匿名内部的格式;new 【父类或接口】(){定义子类的内容}
4.其实匿名内部类就是一个子类对象,而且这个对象有点胖。
也可以理解为代内容的对象。
5.匿名内部类中定义的方法最好不要超过3个
abstract class absdemo{
abstract void show();
}
class outer{
int x=3;
/*class Inner extends absdemo{
void show(){
System.out.println(x);
}
}
//这部分将被简化成匿名内部类,其功能;继承了一个类,
//复写一个函数,创建一个对象,调用一个函数
*/
public void function(){
absdemo d =new absdemo(){//给匿名类起名字 d.show()可直接调用。
public void show(){
System.out.println(x);
}
void abc(){
System.out.println("hh")
}
}.show();//.show之前是一个对象.abc也可以调用
}
}
浙公网安备 33010602011771号