java中的final、static、匿名内部类

341 阅读6分钟

final

package cn.itcast.demo01;
/*
 * 在类的定义上,加上修饰符,final
 * 类最终的,不能有子类,不可以被继承
 * 但是使用方式,没有变化,创建对象,调用方法
 * 
 */
public final class Fu {
	public void show() {
		System.out.println("最终类的方法");
	}
}
package cn.itcast.demo01;
/*
 * 一部分方法写成final修饰
 * 子类可以继承,但是不能做重写
 */
public class Fu1 {
	//这个方法在子类中不能被重写
	public final void show() {
		System.out.println("fu类的最终方法类");
	}
	public void function() {
		System.out.println("父类的一般方法");
	}
}
package cn.itcast.demo01;
/*
 * final 修饰成员变量
 * final 修饰的成员变量,固定的不是内存的默认值
 * 固定的是,成员变量的手动赋值,绝对不是内存的默认
 * 
 * 
 * 成员变量的赋值,2种实现方式,一种是定义的时候,直接赋值
 * 另一种是采取构造方法赋值
 * 保证:被final修饰的成员变量只能被赋值一次。
 * 
 * 成员变量需要在创建对象之前赋值,否则报错
 * 构造方法,是创建对象中的事情,可以为成员变量赋值
 * setXXX方法,创建对象之后的时候,不能为final修饰的成员变量赋值
 */
public class Person {
	//建议使用
	final int age = 1;
	
//	final int age;
//	public Person(int age) {
//		this.age =age;
//	}
}

package cn.itcast.demo01;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		/*Fu f = new Fu();
		f.show();*/
		
		Zi1 z = new Zi1();
		z.show();
		z.function();
		
		final int i = 10;//被final修饰,一次赋值,终身不变,常量
		
		//final 修饰引用变量问题
		//变量保存的内存地址,终身不变
		final Zi1 z2 = new Zi1();
		
		
	}

}
package cn.itcast.demo01;

public class Zi1 extends Fu1{
	@Override
	public void function() {
		// TODO Auto-generated method stub
		super.function();
	}
	//无法被重写
	/*private void show() {
		// TODO Auto-generated method stub

	}*/
}

static(1)

Person.java

package cn.itcast.demo01;

public class Person {
	String name;
	static String className;
}

Student.java

package cn.itcast.demo01;
/*
 * 在静态中不能调用非静态
 * 
 * 因为生命周期不同,静态优先于非静态存在于内存中
 * 
 * 静态不能写this 也不能写 super
 * 
 * 问题:static 应用场景
 * 	static 修饰成员变量,成员方法
 * 
 * 	成员变量加static,根据具体事务,具体分析。
 * 	定义事务的时候,多个事务之间是否有共性的数据
 * 	请你将共性的数据定义为静态的成员变量
 * 	
 * 	成员方法加static,跟着变量走
 * 		如果方法,没有调用过非静态成员,讲方法定义为静态
 * 
 */
public class Student {
	
	private static String name;
	private static int age;
	private char sex;
	
	public void function() {
		System.out.println(name+age+sex);
	}
	//如果方法,没有调用过非静态成员,讲方法定义为静态
	public static int getSum(int a, int b, int c) {
		return a+b+c;
	}
	
	public void show2() {
		System.out.println(sex);
	}
	
	public static void show() {
		System.out.println(name+age);
	}
	
}

Test.java

package cn.itcast.demo01;

public class Test {

	public static void main(String[] args) {
		//
		Person p1 = new Person();
		Person p2 = new Person();
		p1.name = "haha";
		p2.name = "xixi";
		
		//对象调用静态成员变量
		Person.className="基础班";
		
	}

}

static(2)

Fu.java

package cn.itcast.demo02;

public class Zi extends Fu{
	static int i = 2;
	
	public static void show() {
		System.out.println("zi类的静态方法show");
	}
}

Zi.java

package cn.itcast.demo02;

public class Zi extends Fu{
	static int i = 2;
	
	public static void show() {
		System.out.println("zi类的静态方法show");
	}
}

Test.java

package cn.itcast.demo02;
/*
 * 多态调用中,编译看谁,运行看谁
 * 编译都看左边的父类,父类有编译成功,父类没有编译失败
 * 运行,静态方法,运行父类中的静态方法
 * 运行,非静态方法,运行子类的重写方法
 * 成员变量,编译运行全是父类
 * 
 */

public class Test {
	//静态常量
	public static final double PI = 3.14;
	
	public static void main(String[] args) {
		
		Fu f = new Zi();
		//System.out.println(f.i);
		
		//调用的还是父类的静态方法,原因:静态属于类,不属于对象
		//对象的多态性,静态和对象无关,父类的引用,静态方法
		
		f.show();//运行 : 父类的静态方法show
		
		System.out.println(PI);
	}

}

匿名对象

package cn.itcast.demo03;
/*
 * 匿名对象
 * 
 * 有名对象,引用类型变量可以反复使用。
 * 匿名对象,没有引用变量,只能使用一次
 * 
 * 匿名对象当做参数传递
 * 匿名对象当做方法的返回值
 * 
 */
public class Test {

	public static void main(String[] args) {
		//
		Person p = new Person();
		p.eat();
		
		new Person().eat();
		//
		method(p);
		method(new Person());
		
		Person p1 = method();
		p1.eat();
		
	}
	
	public static Person method() {
		return new Person();
	}
	
	//
	public static void method(Person p) {
		p.eat();
	}

}

内部类(1)

Outer.java

package cn.itcast.demo04;
/*
 * 内部类的定义
 * 	成员内部类,可以加上public static.....
 * 调用规则:内部类,可以使用外部类成员,包括私有
 * 		外部类要使用内部类的成员,必须建立内部类对象
 */
public class Outer {
	
	private int a = 1;
	
	//外部类成员位置,定义内部类
	class Inner{
		public void inner() {
			System.out.println("内部类方法"+a);
		}
	}
	
}

Test.java

package cn.itcast.demo04;

public class Test {

	public static void main(String[] args) {
		/*
		 *  调用外部类中的内部类的方法inner()
		 *  依靠外部类对象,找到内部类,通过内部类对象,调用内部类的方法
		 *  格式:
		 *    外部类名.内部类名  变量 = new 外部类对象().new 内部类对象();
		 *    变量.内部类方法()
		 */
		Outer.Inner in = new Outer().new Inner();
		in.inner();
		
		
		
	}

}

内部类(2)

Outer.java

package cn.itcast.demo05;

public class Outer {
	int i = 1;
	class Inner{
		int i = 2;
		public void inner() {
			//System.out.println("内部类方法");
			int i = 3;
			//访问外部的成员变量
			System.out.println(Outer.this.i);
		}
	}
}

Test.java

package cn.itcast.demo05;

public class Test {

	public static void main(String[] args) {
		// 
		Outer.Inner in = new Outer().new Inner();
		in.inner();
		
	}

}

局部内部类

Outer.java

package cn.itcast.demo06;
/*
 * 局部内部类
 */
public class Outer {
	
	public void out() {
		
		class Inner{
			public void inner() {
				System.out.println("局部内部类方法");
			}
		}
		
		Inner in= new Inner();
		in.inner();
		
		
	}
	
	public void out2() {
		
		class Inner{
			public void inner() {
				System.out.println("局部内部类方法");
			}
		}
		
	}
}

调用

//调用局部内部类的方法inner
		new Outer().out();

匿名内部类(1)

Smoking.java

package cn.itcast.demo07;

public interface Smoking {
	public abstract void smoking();
}
/*
 *  实现类,实现接口 重写接口抽象方法,创建实现类对象
 *  class XXX implements Smoking{
 *      public void smoking(){
 *      
 *      }
 *  }
 *  XXX x = new XXX();
 *  x.smoking(); 
 *  Smoking s = new XXX();
 *  s.smoking();
 *  
 *  匿名内部类,简化问题:  定义实现类,重写方法,建立实现类对象,合为一步完成
 */

Test.java

package cn.itcast.demo07;

public class Test {

	public static void main(String[] args) {
		//使用匿名内部类
		/*
		 *  定义实现类,重写方法,创建实现类对象,一步搞定
		 *  格式:
		 *    new 接口或者父类(){
		 *       重写抽象方法
		 *    };
		 *    从 new开始,到分号结束
		 *    创建了接口的实现类的对象
		 */
		new Smoking() {
			
			@Override
			public void smoking() {
				//
				System.out.println("人在吸烟");
			}
		}.smoking();

	}

}

匿名内部类(2)

Animal.java

package cn.itcast.demo07;

public abstract class Animal {
	public abstract void eat();
	public abstract void sleep();
}

Test.java

package cn.itcast.demo07;

import java.util.concurrent.locks.Lock;

/*
 *    new Animal(){
			public void eat(){
				System.out.println("在吃饭");
			} 
			public void sleep(){
				System.out.println("在睡觉");
			}
		 };
	以上代码,就是Animal的子类的对象
	多态性, 父类引用 = 子类的对象

 */
public class Test2 {
	public static void main(String[] args) {
		
		Lock lock = null;
		
		
		Animal a= new Animal(){
			public void eat(){
				System.out.println("吃饭);
			} 
			public void sleep(){
				System.out.println("睡觉");
			}
		 };
		 a.eat();
		 a.sleep();
	}
}

代码块的使用

Person.java

package cn.itcast.demo08;
/*
 *  静态代码块, 只执行一次
 *  构造代码块,new一次,就执行一次,优先于构造方法
 *  构造方法, new 一次,就执行一次
 */
public class Person {
  private String name;
  private int age;
  

  public Person(String name,int age){
	  this.age = age;
	  this.name = name;
	  System.out.println("我是构造方法");
  }
  //构造代码块
  {
	  System.out.println("我是构造代码块");
  }
  
  //静态代码块
  static{
	  System.out.println("我是静态代码块");
  }
}

Test.java

package cn.itcast.demo08;

public class Test {

	public static void main(String[] args) {
		//局部变量代码快
		{
			int a = 1;
			System.out.println(a);
		}
		
		new Person("张三",20);
		new Person("张三2",220);
	}

}