面向对象基础语法2
回调机制
回调机制1
package com.ice.回调机制;
public class SuperCalculator {
public void add(int a,int b,Myself myself){
int result=a+b;
//I will call back
myself.getResult(a, b, result);
}
}
class Myself{
//if you call me
public void useSuperCalculator(int a,int b){
new SuperCalculator().add(a, b, this);
}
public void getResult(int a,int b,int result){
System.out.println("使用回调计算器的结果:"+result);
}
}
class Test{
public static void main(String[] args) {
new Myself().useSuperCalculator(218, 342);
}
}
回调机制2
package com.ice.回调机制2;
public interface DoWork {
void getResult(int a,int b,int result);
}
class SuperCalculator{
//回调MySelf中的方法
public void add(int a,int b,DoWork doWork){//参数为接口类型,那么回调方法时由实现类对象来决定
int result = a+b;
doWork.getResult(a, b, result);
}
}
class MySelf implements DoWork{
//去调用SuperCalculator中的方法
public void useSuperCalculator(int a,int b){
new SuperCalculator().add(a, b, this);
}
@Override
public void getResult(int a, int b, int result) {
System.out.println("使用回调机制的结果:"+result);
}
}
class Test{
public static void main(String[] args) {
new MySelf().useSuperCalculator(33, 23);
}
}
面向对象基础语法3
static
static修饰的方法或代码块中不能使用this与super关键字,static不能修饰构造器
static修饰的方法或变量可以直接使用“类名.”调用(标准),“对象.”(非标准)。
被static修饰的变量,方法或代码块在相应类中具有全局性。static只能在类中使用。
static修饰代码块,用于初始化静态变量,先于构造器执行,创建对象的次数决定了构造器的执行次数,也决定了非静态代码块的执行次数,但不影响静态代码块的执行次数,创不创建对象,静态代码块都只被执行一次。
单例设计模式
在一个项目中,把一个类的对象设计成只能被创建一次,任何时候,任何地方也使用该类的对象时,实际上使用到的都是该类的同一个对象。
懒汉式
package cn.iceson.singleton;
public class SingleTon {
protected double d=Math.random();//生成0~1之间的随机一个浮点数
private static SingleTon singleTon=null;
//私有化构造器,不让其他类创建本类的对象
private SingleTon(){
}
//静态工厂:专门用来生成类的实例
public static SingleTon singleTon2(){
if(singleTon==null){
singleTon=new SingleTon();
}
return singleTon;
}
}
测试类
package cn.iceson.singleton;
public class Test {
public static void main(String[] args) {
SingleTon singleTon = SingleTon.singleTon2();
System.out.println(singleTon.d);
SingleTon singleTon2 = SingleTon.singleTon2();
System.out.println(singleTon2.d);
}
}
/*
其中一次的执行结果为:
0.7041090609815749
0.7041090609815749
*/
饿汉式
package cn.iceson.singleton;
public class SingleTon {
protected double d=Math.random();//生成0~1之间的随机一个浮点数
private static SingleTon singleTon=new SingleTon();
//私有化构造器,不让其他类创建本类的对象
private SingleTon(){
}
//静态工厂:专门用来生成类的实例
public static SingleTon singleTon2(){
return singleTon;
}
}
测试类
package cn.iceson.singleton;
public class Test {
public static void main(String[] args) {
SingleTon singleTon = SingleTon.singleTon2();
System.out.println(singleTon.d);
SingleTon singleTon2 = SingleTon.singleTon2();
System.out.println(singleTon2.d);
}
}
/*
其中一次的执行结果为:
0.7041090609815749
0.7041090609815749
*/
内部类
两个接口,每个接口中都有一个方法,这两个方法的方法名称和方法参数都相同,一个实现类来实现这两个接口,这个时候,实现类只会重写一个方法,另外一个方法就没有了。此时使用内部类可以解决此问题。
在类中或在类的成员方法中创建的类称为内部类。
内部类分为四种:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
不管是哪种内部类,内部类都可以是普通类或抽象类的子类,也可以是接口的实现内部类。
内部类实现接口
接口1
package cn.iceson;
public interface Inf1 {
//启动
void start();
}
接口2
package cn.iceson;
public interface Inf2 {
// 开始
void start();
}
实现类
package cn.iceson;
public class OuterClass implements Inf1{
//内部类
class InnerClass{
}
//内部类实现接口
class InnerClassInf implements Inf2{
//开始
@Override
public void start() {
// TODO Auto-generated method stub
}
}
//启动
@Override
public void start() {
// TODO Auto-generated method stub
}
}
内部类继承抽象类
其他类
package cn.iceson2;
public class Other {
}
抽象类
package cn.iceson2;
public abstract class Abstr {
public abstract void start();
}
内部类
package cn.iceson2;
public class OuterClass extends Other {
//内部类
class InnerClass extends Abstr{
@Override
public void start() {
// TODO Auto-generated method stub
}
}
}
类中的成员
package cn.iceson3;
public abstract class OuterClass {
int a;//普通成员变量
static int b;//静态成员变量
static final int C=10;//常量
{
//初始化块
}
static{
//静态初始化块
}
public OuterClass(){
//构造器
}
public void f1(){
//普通成员方法
}
public static void f2(){
//静态方法
}
public abstract void f3();//抽象方法
class InnerClass{
//内部类
}
}
成员内部类
成员内部类创建在类中、方法外,可以使用四个访问权限修饰符修饰。
成员内部类中不可以有静态成员。
外部类可以使用成员内部类。
成员内部类的实例方法中拥有有外部类对象,使用"外部类名.this"获取,所以可以使用"外部类名.this"访问外部类
成员(内部类的实例方法中 this表示内部类对象,外部类名.this表示外部类对象);
package cn.iceson4;
public class OuterClass {
int a=10;//成员变量
static int b=20;//静态变量
/**
* 在外部类中访问成员内部类
* @author lucky_ice
*
*/
//成员方法
public void fun(){
System.out.println(new InnerClass().x);
}
class InnerClass{
int x=100;
// static int y=200;//成员内部类中不能存在静态成员
/**
* 在内部类中访问外部成员:类名.this.成员名
* 在内部类中的this表示当前的内部类对象
*/
public void fun(){
System.out.println(OuterClass.this.a);
System.out.println(OuterClass.b);
System.out.println(this.x);
}
}
}
静态内部类
静态内部类创建在类中,方法外,使用static修饰;
四种访问权限修饰符都可以修饰静态内部类,类可以被任何地方使用,其它类使用静态内部类时,要受静态内部类
的权限修饰符影响,这种影响与类中成员变量或成员方法一样;
导入静态内部类的包的格式为import …外部类.静态内部类;
只导入静态内部类的外部类也可以使用静态内部类,只是使用时格式为“外部类.内部类.";
静态内部类中可以有静态成员变量与静态成员方法。
静态内部类的实例方法中没有外部类对象,所以不能在静态内部类中使用"外部类.this”,即静态内部类只能访问外
部类的静态成员,不能访问外部类的实例成员
局部内部类
方法中定义的内部类
局部内部类与局部变量有很多相似之处
一都不可使用权限修饰符修饰
一作用域范围相同,都是定义地方起到第一个""}"结束
局部内部类拥有外部类对象,即可以使用"外部类名.this"访问外部类成员
局部内部类中可访问外部方法的局部变量,但是该局部变量必须是final修饰的。
package cn.iceson4;
public class OuterClass {
int a=10;//成员变量
public void fun(){
int x=20;
class InnerClass{
private void pub() {
System.out.println(OuterClass.this.a);//访问成员变量
System.out.println(x);//jdk1.8之后的局部变量默认加上了final修饰,因此在局部内部类中可以直接访问局部变量
}
}
}
}
匿名内部类
- 匿名内部类一定是跟在一个new关键字后面
- 匿名内部类可以在外部类成员变量赋值是创建
- 匿名内部类可以在方法体中直接创建并使用,并且可以与局部内部类一样可以访问外部方法的final修饰的局部变量
- 匿名内部类可以在调用方法传参时创建
- 匿名内部类中拥有外部类对象,即可以使用"外部类名.this"访问外部类成员
- 开发中经常使用匿名内部类实现回调
package cn.iceson6;
public class Animal {
public void eat(){
System.out.println("eat...");
}
}
package cn.iceson6;
/**
* 匿名内部类
* 1.在成员变量赋值时创建
* 2.在方法内部创建并直接使用
* 3.在方法参数位置创建
* @author lucky_ice
*
*/
public class NoNameClass {
Animal animal=null;//声明引用变量时使用默认值null
Animal animal2=new Animal();//声明引用变量时就创建对象
/**
* 1.在成员变量赋值时创建
* 声明引用变量并创建匿名内部类对象:new 类名(){}
*/
Animal animal3=new Animal(){
@Override
public void eat(){
System.out.println("匿名内部类方法");
};
};
/**
* 2.在方法内部创建并直接使用
*/
public void fun(){
//匿名内部类---》匿名对象,用完一次就回收
new Animal(){};
Animal animal=new Animal(){
@Override
public void eat(){
System.out.println("匿名内部类的eat方法");
}
};
animal.eat();
}
/**
* 3.在方法参数位置创建
*/
public void name(Animal animal) {
animal.eat();
}
public static void main(String[] args) {
new NoNameClass().name(new Animal(){});//3.在方法参数位置创建
}
}
package cn.iceson7;
public class Animal {
public void sleep(){
System.out.println("Animal sleep...");
}
}
package cn.iceson7;
public interface Mouse {
public void click();
}
package cn.iceson7;
public abstract class Computer {
public abstract void play();
}
package cn.iceson7;
public class NoNameClass {
public void fun(){
//普通类实现匿名内部类
Animal animal=new Animal(){
@Override
public void sleep() {
// TODO Auto-generated method stub
super.sleep();
System.out.println("匿名内部类的Animal sleep方法");
}
};
//接口实现匿名内部类,在匿名内部类中必须重写抽象方法
Mouse mouse=new Mouse() {
@Override
public void click() {
System.out.println("Mouse click...");
}
};
//抽象类实现匿名内部类,在匿名内部类中必须重写抽象方法
Computer computer=new Computer() {
@Override
public void play() {
System.out.println("Computer play...");
}
};
}
}
使用匿名内部类作为参数传递
package cn.iceson8;
public class Animal {
public void sleep(){
System.out.println("Animal sleep...");
}
}
class Dog extends Animal{
@Override
public void sleep() {
// TODO Auto-generated method stub
super.sleep();
System.out.println("Animal sleep...1");
}
}
package cn.iceson8;
public abstract class Computer {
public abstract void play();
}
class MyComputer extends Computer{
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("MyComputer play...1");
}
}
package cn.iceson8;
public interface Mouse {
public void click();
}
class Lenovo implements Mouse{
@Override
public void click() {
// TODO Auto-generated method stub
System.out.println("Lenovo click...1");
}
}
package cn.iceson8;
public class NoNameClass {
//普通类作为参数时:可以传递普通类对象、子类对象、匿名内部类
public void m1(Animal a){
a.sleep();
}
//抽象类作为参数时:可以传递子类对象、匿名内部类
public void m2(Computer c){
c.play();
}
//接口作为参数时:可以传递实现类对象、匿名内部类
public void m3(Mouse m){
m.click();
}
}
package cn.iceson8;
public class Test {
public static void main(String[] args) {
NoNameClass nameClass=new NoNameClass();
/*nameClass.m1(new Animal());//普通类的匿名对象
nameClass.m1(new Dog());//向上转型,子类对象
nameClass.m1(new Animal(){//匿名内部类对象
@Override
public void sleep() {
// TODO Auto-generated method stub
super.sleep();
System.out.println("Animal sleep...2");
}
});
nameClass.m1(new Dog(){
@Override
public void sleep() {
// TODO Auto-generated method stub
super.sleep();
System.out.println("Animal sleep...3");
}
});*/
/*nameClass.m2(new MyComputer());
nameClass.m2(new Computer() {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("Computer play...2");
}
});
nameClass.m2(new MyComputer(){
@Override
public void play() {
// TODO Auto-generated method stub
super.play();
System.out.println("MyComputer play...3");
}
});
*/
nameClass.m3(new Lenovo());//向上转型
nameClass.m3(new Mouse() {
@Override
public void click() {
// TODO Auto-generated method stub
System.out.println("Mouse click...2");
}
});
}
}
修饰符适用范围
修饰符名称|范围 | 类 | 属性 | 方法 | 构造器 | 初始化块 | 内部类 |
---|---|---|---|---|---|---|
public | Y | Y | Y | Y | Y | |
protected | Y | Y | Y | Y | ||
default | Y | Y | Y | Y | Y | Y |
private | Y | Y | Y | Y | ||
final | Y | Y | Y | Y | ||
abstract | Y | Y | Y | |||
static | Y | Y | Y | Y |