首页 > 其他 > 详细

十二、类的高级特性

时间:2020-12-27 15:38:46      阅读:16      评论:0      收藏:0      [点我收藏+]

1、Java类包 

一个完整的类名需要包名与类名的组合,任何一个类都隶属于一个类包,只要保证同一类包中的类不同名,就可以有效地避免同名类冲突的情况。

使用import关键字导入包。

2、final变量

final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。

通常,由final定义的变量为常量。例如,在类中定义PI值,可以使用如下语句:final double PI=3.14;

3、final方法

定义为final的方法不能被重写。

将方法定义为final类型可以防止任何子类修改该类的定义与实现方式,同时定义为final的方法执行效率要高于非final方法。

如果一个父类的某个方法被设置为private修饰符,子类将无法访问该方法,自然无法覆盖该方法,所以一个定义为private的方法隐式被指定为final类型,这样无须将一个定义为private的方法再定义为final类型。

4、final类

定义为final的类不能被继承。

如果希望一个类不允许任何类继承,并且不允许其他人对这个类有任何改动,可以将这个类设置为final形式。

final类的语法如下:final 类名{}

如果将某个类设置为final形式,则类中的所有方法都被隐式设置为final形式,但是final类中的成员变量可以被定义为final或非final形式。

5、内部类

5.1 成员内部类

最常见的内部类就是成员内部类,也称作普通内部类;

public class Outer {
    private int a = 1;
    private String name = "张胜男";
    //成员内部类
    public class Inner{
        int b = 2;
        String name = "李伟";
        public void test(){
            System.out.println("a:"+a);
            System.out.println("b:"+b);
            System.out.println("外部类的名字:"+Outer.this.name);
            System.out.println("内部类的名字:"+name);
        }
    }
    public static void main(String[] args) {
        Outer outer = new Outer();//创建外部类
        Inner inner = outer.new Inner();//通过外部类创建内部类
        inner.test();//调用内部类方法
    }
}

1)Inner类定义在Outer类的内部,相当于Outer类的成员变量的位置,Inner类可以使用任意访问修饰符,如:public、private、protected等。

2)Inner类中定义的test()方法可以访问Outer类中的数据,不受访问控制符的影响。

3)定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );如创建Inner的内部类对象:要先创建外部类对象:Outer o = new outer(); 创建内部类:Inner i = o.new Inner();访问Inner中的test()方法:i.test();

4)如果外部类和内部类具有相同的成员变量或方法,内部类可以直接访问内部类的成员变量或方法,但如果内部类访问外部类的成员变量或者方法时,需要使用this关键字;

5.2 局部内部类

定义在方法中的内部类,方法内部类只在该方法内可以用。

public class Outer {
    private int a = 1;
    private String name = "张胜男";
    
    public void show(){
        int b = 22;
        //局部内部类(方法内部类)
        class Inner{
            int c = 2;
            String name = "李伟";
            public void test(){
                System.out.println("a:"+a);
                System.out.println("外部类的名字:"+Outer.this.name);
                //这里b并没有用final修饰(1.8之后java隐式的将b修饰为final)如果你添加一个x=8,这里就会报错。
                System.out.println("外部类方法的属性b:"+b);
                System.out.println("内部类的名字:"+name);
            }
        }
        Inner inner = new Inner();
        inner.test();
    }
    
    public static void main(String[] args) {
        Outer outer = new Outer();//创建外部类
        outer.show();
    }
}

注意:

1)由于方法内部类不能在外部类的方法以外的地方使用,内部类不能被public、private、static修饰;

2)在外部类中不能创建局部内部类的实例;

3)创建局部内部类的实例只能在包含他的方法中;

4)局部内部类访问包含他的方法中的变量必须有final修饰;

5)外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后。

为什么局部内部类调用外部类方法的属性要用final修饰?

主要原因还是生命周期:当方法return后,方法中的局部变量就会随之销毁,但是我的内部类对象可能仍然还存在的(当不在被使用才会被垃圾回收器回收)这时在内部类中访问了局部变量x,但此时的x已经被销毁,内部类访问了一个并不会存在的变量,这就形成了一个矛盾。

根本原因就是:内部类的生命周期比局部变量的长。

5.3 匿名内部类

匿名内部类可以使你的代码更加简洁,你可以在定义一个类的同时对其进行实例化。它与局部类很相似,不同的是它没有类名,如果某个局部类你只需要用一次,那么你就可以使用匿名内部类.

特点:

* 可以把匿名内部类看成是一个没有名字的局部内部类。

* 定义在方法当中。

* 必须在定义匿名内部类的时候创建他的对象。

//A:作用:匿名内部类是创建某个类型子类对象的快捷方式。
//B:格式:
new 父类或接口(){
  //进行方法重写
//如果是创建了继承这个类的子类对象,我们可以重写父类的方法
//如果是创建了实现这个接口的子类对象,我们必须要实现该接口的所有方法
}; //已经存在的父类: public abstract class Person{   public abstract void eat(); } //定义并创建该父类的子类对象,并用多态的方式赋值给父类引用变量 Person p = new Person(){   public void eat() {     System.out.println(“我吃了”);   } }; //调用eat方法 p.eat(); //使用匿名对象的方式,将定义子类与创建子类对象两个步骤由一个格式一次完成,。虽然是两个步骤,但是两个步骤是连在一起完成的。 //匿名内部类如果不定义变量引用,则也是匿名对象。代码如下: new Person(){   public void eat() {     System.out.println(“我吃了”);   } }.eat();

匿名内部类注意事项:

* 匿名内部类不能有构造方法;

* 匿名内部类不能定义任何静态成员、方法和类

* 匿名内部类不能有public、protected、private、static

* 只能创建匿名内部类的一个实例

* 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类

* 匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效

* 在匿名内部类中使用this时,这个this指的是匿名类本身。如果要使用外部类的方法和变量的话,应该加上外部类的类名。

5.4 静态内部类

一个静态内部类中可以声明static成员,但是在非静态内部类中不可以声明静态成员。静

态内部类有一个最大的特点,就是不可以使用外部类的非静态成员,所以静态内部类在程序开发中比较少见。

public class Outer {
    private int a = 1;
    private static String name = "张胜男";
    //成员内部类
    public static class Inner{
        int b = 2;
        String name = "李伟";
        public void test(){
            System.out.println("a:"+new Outer().a);
            System.out.println("外部类的名字:"+Outer.name);
            System.out.println("内部类的名字:"+name);
        }
    }
    public static void main(String[] args) {
        Inner inner = new Inner();//直接创建静态内部类
        inner.test();//调用静态内部类方法
    }
}

1)静态内部类不能直接访问外部类的非静态成员,但,可以通过new 外部类().成员的方式访问;

2)如果外部类的静态成员与内部类的静态成员相同, 可以通过"类名.静态成员"来访问外部类的静态成员;如果不同,可以直接调用外部类的静态成员名。

3)创建静态内部类的对象时,不需要外部类的对象,可以直接创建;

5.5 内部类的继承

内部类和其他普通类一样,同样可以被继承,这样给本来就十分灵活的内部类增加了更好的结构性和代码复用性。

只是内部类的继承和普通类有一些不同之处,是在使用时需要多加注意的。因为内部类在创建时需要外部类的引用,所以在内部类的继承上也需要外部类的协助。

class WithInner{
  class Inner{
  }
}
public class test3 extends WithInner.Inner{
  test3(WithInner wi){
  wi.super();
}
public static void main(String[] args){
  WithInner wi = new WithInner();
    test3 t3 = new test3(wi);
  }
}

首先在继承语句extends处,注意命名空间,需要加上外围类名,才能对应上正确的内部类。

其次是构造对象上,这里需要自己写一个接受外围类引用的构造器,来给导出类提供创建对象的基本环境。

注意在构造器中的这一句wi.super()这是必须在构造器中使用的,才能够成功的构造出一个继承自内部类的对象。

 

十二、类的高级特性

原文:https://www.cnblogs.com/ljk-shm-0208/p/14196905.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!