1.finial变量
final 关键字可用于变量的声明,一旦该变量被设定,就不可以再改变该变量的值,通常,由final定义的变量为常量,常量定义时要以大写字母开头,中间以_连接。
final double PI=3.14;
一旦一个对象引用被修饰为final后,他只能恒定指向一个对象,无法将其改变以指向另一个对象,但是一个对象本身的值是可以更改的,若让常量真正做到不可更改,则要加static,一个既是static又是final的字段只占据一段不能改变的存储空间。
package hello;
import static java.lang.System.out;
import java.util.Random;
public class FinalStaticData {
private static Random rand = new Random(); // 实例化一个Random类对象
// 随机产生0~10之间的随机数赋予定义为final的a1
private final int a1 = rand.nextInt(10);
// 随机产生0~10之间的随机数赋予定义为static final的a2
private static final int a2 = rand.nextInt(10);
//再实例化一个对象时,仍然指向a2这块内存区域,a2的值不变;
//a2是在装载时被初始化,而不是每次创建对象时被初始化,而a1会在重新实例化对象时被更改。
public static void main(String[] args) {
FinalStaticData fdata = new FinalStaticData(); // 实例化一个对象
// 调用定义为final的a1
out.println("重新实例化对象调用a1的值:" + fdata.a1);
// 调用定义为static final的a2
out.println("重新实例化对象调用a1的值:" + fdata.a2);
// 实例化另外一个对象
FinalStaticData fdata2 = new FinalStaticData();
out.println("重新实例化对象调用a1的值:" + fdata2.a1);
out.println("重新实例化对象调用a2的值:" + fdata2.a2);
}
}
public class Main{
final int VALUE_ONE=6;//final成员变量不可更改
final int BLANK_FINALVALUE;//空白final
public Main()
{
BLANK_FINALVALUE=9;//在构造方法中为空白final 赋值
}
int doIt(final int x)//设置final参数,不可以改变参数x的值
{
return x+1;
}
void doSomething()
{
final int i=9;//局部变量定义为final,不可以改变i的值。
}
}
final型变量,系统不会给它赋初值.
final有static修饰的时候,只能在声明的时候直接给它赋值.别处没法对它进行赋值
比如,在构造方法里给它赋值,会报错,错误分析:静态变量(不需任何对象)直接由类名调用. final没有static修饰的时候,有两种赋值:1.直接赋值.2在构造方法里给它赋值.每个构造方法必须给它赋值.
2.finial方法
final方法不能被重写,可以防止子类修改该类的定义与实现方式,同时效率较高,被定义为private的父类,子类自然无法访问该方法,也无法覆盖该方法,所以一个定义为private的方法隐式被指定为final类型,这样无需将一个定义为private的方法再定义为final类型。但是在父类中被定义为private final的方法似乎可以被子类覆盖。
package hello;
class Parents {
private final void doit() {
System.out.println("父类.doit()");
}
final void doit2() {
System.out.println("父类.doit2()");
}
public void doit3() {
System.out.println("父类.doit3()");
}
}
class Sub extends Parents {
public final void doit() { // 在子类中定义一个doit()方法
System.out.println("子类.doit()");
}
// final void doit2(){ //final方法不能覆盖
// System.out.println("子类.doit2()");
// }
public void doit3() {
System.out.println("子类.doit3()");
}
}
public class Main {
public static void main(String[] args) {
Sub s = new Sub(); // 实例化
s.doit(); // 调用doit()方法
Parents p = s; // 执行向上转型操作
// p.doit(); //不能调用private方法
p.doit2();
p.doit3();
}
}
/*
子类.doit()
父类.doit2()
子类.doit3()
*/
3.finial类
定义为final的类不能被继承。
package hello;
final class Main {
int a = 3;
void doit() {
}
public static void main(String args[]) {
Main f = new Main();
f.a++;
System.out.println(f.a);
}
}
1.成员内部类
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量,尽管外部类的成员被修饰为private,在内部类中依旧可以直接使用外部类的类成员,但是内部类的成员只有在内部类的范围内是已知的。非内部类不能被声明为private或protected 访问类型。
public class OuterClass { //外部类
private class InnerClass{ //内部类
//...
}
}
package hello;
public class OuterClass {
innerClass in = new innerClass(); // 在外部类实例化内部类对象引用
public void ouf() {
in.inf(); // 在外部类方法中调用内部类方法
}
class innerClass {
innerClass() { // 内部类构造方法
}
public void inf() { // 内部类成员方法
}
int y = 0; // 定义内部类成员变量
}
public innerClass doit() { // 外部类方法,返回值为内部类引用
// y=4; //外部类不可以直接访问内部类成员变量
in.y = 4;
return new innerClass(); // 返回内部类引用
}
public static void main(String args[]) {
OuterClass out = new OuterClass();
// 内部类的对象实例化操作必须在外部类或外部类中的非静态方法中实现
OuterClass.innerClass in = out.doit();
OuterClass.innerClass in2 = out.new innerClass();
}
}package hello;
public class OuterClass {
innerClass in = new innerClass(); // 在外部类实例化内部类对象引用
public void ouf() {
in.inf(); // 在外部类方法中调用内部类方法
}
class innerClass {
innerClass() { // 内部类构造方法
}
public void inf() { // 内部类成员方法
}
int y = 0; // 定义内部类成员变量
}
public innerClass doit() { // 外部类方法,返回值为内部类引用
// y=4; //外部类不可以直接访问内部类成员变量
in.y = 4;
return new innerClass(); // 返回内部类引用
}
public static void main(String args[]) {
OuterClass out = new OuterClass();
// 内部类的对象实例化操作必须在外部类或外部类中的非静态方法中实现
OuterClass.innerClass in = out.doit();
OuterClass.innerClass in2 = out.new innerClass();
}
}
(1)内部类向上转型为接口
package hello;
interface OutInterface { // 定义一个接口
public void f();
}
public class Main {
public static void main(String args[]) {
OuterClass2 out = new OuterClass2(); // 实例化一个OuterClass2对象
// 调用doit()方法,返回一个OutInterface接口
OutInterface outinter = out.doit();
outinter.f(); // 调用f()方法
}
}
class OuterClass2 {
// 定义一个内部类实现OutInterface接口
private class InnerClass implements OutInterface {
InnerClass(String s) { // 内部类构造方法
System.out.println(s);
}
public void f() { // 实现接口中的f()方法
System.out.println("访问内部类中的f()方法");
}
}
public OutInterface doit() { // 定义一个方法,返回值类型为OutInterface接口
return new InnerClass("访问内部类构造方法");
}
}
/*输出:
访问内部类构造方法
访问内部类中的f()方法
*/
//由于内部类InnerClass的修饰权限为private,所以除了OuterClass类可以访问,其他类都不能访问,但是可以访问doit()方法,如果某个类继承了外部类,由于内部的权限不可以向下转型为内部类的,也不能访问f()方法,但是可以通过接口访问接口中的f() 方法。
(2)使用this关键字获取内部类与外部类的引用
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。
public class Main {
private int x;
private class Inner {
private int x = 9;
public void doit(int x) {
x++; // 调用的是形参x
this.x++; // 调用内部类的变量x
Main.this.x++; // 调用外部类的变量x
}
}
}
2.局部内部类
package hello;
interface OutInterface2 { // 定义一个接口
}
class OuterClass3 {
public OutInterface2 doit(final String x) { // doit()方法参数为final类型
// 在doit()方法中定义一个内部类
class InnerClass2 implements OutInterface2 {
InnerClass2(String s) {
s = x;
System.out.println(s);
}
}
return new InnerClass2("doit");
}
}
内部类InnerClass2是doit() 方法的一部分,并不是OuterClass3类中的一部分,所以在doit() 方法的外部不能访问该内部类,但该内部类可以访问当前代码块的常量以及此外部类的所有成员;如果需要在方法体内使用局部变量,该局部变量要被设置为final类型,也就是说,在方法中定义的内部类只能访问方法中final类型的局部变量。
3.匿名内部类
class OuterClass3 {
public OutInterface2 doit()
{
return new InnerClass2 //创建一个实现于..face2接口的匿名类的对象
{
private int i=0;
public int getValue()
{
return i;
}
};//分号并不代表定义内部类结束的标识,而是代表创建..face2引用表达式的标识
}
}
4.静态内部类
在内部类前加static修饰符,就是静态内部类,一个静态内部类可以声明static成员,但是非静态内部类中不可以声明静态成员,静态内部类不可以使用外部类的非静态成员。
5.内部类的继承
package hello;
class ClassA{
class ClassB{
}
}
public class Main extends ClassA.ClassB{//
public Main(ClassA a){
a.super();
}
/*public static void main(String[] args){
ClassA A=new ClassA();
Main n=new Main(A);
}*/
}
在某个类继承内部类时,必须硬性给予这个类一个带参数的构造方法,并且该构造方法的参数为需要继承内部类的外部类的引用,同时在构造方法体中个使用a.supper()语句,这样才为继承提供了必要的对象引用。