内部类
内部类:就是在一个类中定义另一个类
内部类分类:按照内部类在外部类中定义的位置不同划分
1.成员内部类:定义在外部类的成员位置
成员内部类创建对象格式:外部类名.内部类名 对象名=new 外部类名().new 内部类名();
成员内部类属于外部类成员,可以被一些修饰符修饰,
2.局部内部类:定义在外部类的局部位置,(在方法当中),外界无法直接使用,需要在方法内部创建对象并使用
局部内部类可以直接访问外部类的成员,也可以访问方法内部的局部变量
内部类可以直接访问外部类的成员变量(包括私有)
外部类访问内部类需创建对象
public class TestInner {
public static void main(String[] args) {
Outer.Inner inner=new Outer().new Inner();
System.out.println(inner.num);
inner.show();
}
}
class Outer{
private int i=1;
class Inner{
int num = 1;
public void show(){
System.out.println("inner.show()");
System.out.println(i);
}
}
}
public class TestInner {
public static void main(String[] args) {
Outer1 outer=new Outer1();
outer.method();
}
}
class Outer1{
private class Inner1{
int num = 1;
public void show(){
System.out.println("inner.show()");
}
}
public void method(){
Inner1 inner=new Inner1();
inner.show();
}
}
public class TestInner {
public static void main(String[] args) {
Outer2.Inner2 oi=new Outer2.Inner2();
oi.show();
Outer2.Inner2.show1();
}
}
class Outer2{
static class Inner2{
static int num = 1;
public void show(){
System.out.println("inner.show()");
}
public static void show1(){
System.out.println("inner.show()");
}
}
}
public class TestInner {
public static void main(String[] args) {
Outer3 o=new Outer3();
o.method();
}
}
class Outer3{
int a=100;
public void method(){
int b=200;
class Inner{
public void show(){
System.out.println("Inner.show..");
System.out.println(a);
System.out.println(b);
}
}
Inner inner=new Inner();
inner.show();
}
}
匿名内部类
匿名内部类:定义在方法内部,是一个特殊的局部内部类
前提:需要存在一个接口或类
格式:new 接口或类名(){重写方法}
public class Anonymity {
public static void main(String[] args) {
new Inter(){
@Override
public void show() {
System.out.println("InterImpl重写Inter类show方法");
}
}.show();
Inter2 inter2=new Inter2(){
@Override
public void show1() {
System.out.println("Inter的show1");
}
@Override
public void show2() {
System.out.println("Inter的show2");
}
};
inter2.show1();
inter2.show2();
}
}
interface Inter{
void show();
}
interface Inter2{
void show1();
void show2();
}
public class Anonymity01 {
public static void main(String[] args) {
SwimmingImpl s=new SwimmingImpl();
goSwimming(s);
goSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("去游泳");
}
});
}
public static void goSwimming(Swimming swimming){
swimming.swim();
}
}
interface Swimming{
void swim();
}
class SwimmingImpl implements Swimming{
@Override
public void swim() {
System.out.println("游泳");
}
}
lambda
lambda表达式三要素:形参,箭头,代码块
(形式参数)->{代码块},括号(参数列表)跟匿名内部类重写的方法括号一样
形参可有可无,如果有多个用逗号隔开,->代表指向动作
使用前提:需要接口(只能操作接口,不能操作类)
接口中有且仅有一个抽象方法
简写格式: 参数类型(一个参数还可以省参数的小括号),大括号、return、分号(语句只有一条)都可以省略
因为只有一个抽象方法,
可推断就可省
函数式编程思想:重点是做什么
匿名内部类和lambda表达式输出结果一样
匿名内部类和lambda区别:
所需类型不同:
匿名内部类:可以是接口,可以是抽象类,还可以是具体类
lambda:只能是接口
使用限制不同:
如果接口中有且仅有一个抽象方法,两者都可使用
如果多于一个,只能使用匿名内部类
实现原理不同:
匿名内部类:编译之后,产生一个.class字节码文件
lambda:编译之后,没有一个单独的.class字节码文件,对应的字节码会在运行的时候动态生成
public class Test01 {
public static void main(String[] args) {
useStringHandler(()->{
System.out.println("useStringHandler");
});
}
public static void useStringHandler(StringHandler stringHandler ){
stringHandler.printMessage();
}
}
interface StringHandler{
void printMessage();
}
public class Test02 {
public static void main(String[] args) {
useRandomNumHandler(()->{
Random r=new Random();
int num=r.nextInt(10) + 1;
return num;
});
}
public static void useRandomNumHandler(RandomNumHandler randomNumHandler){
int number = randomNumHandler.getNumber();
System.out.println(number);
}
}
interface RandomNumHandler{
int getNumber();
}
public class Test03 {
public static void main(String[] args) {
useMessage(( str)->{
System.out.println(str);
});
}
public static void useMessage(Message message){
message.envelop("tz");
}
}
interface Message{
void envelope(String str);
}
public class Test04 {
public static void main(String[] args) {
useInterSum(( a, b)->a+b);
}
public static void useInterSum(Inter inter){
double sum=inter.getSum(18.7,19.8);
System.out.println(sum);
}
}
interface Inter{
double getSum(double a,double b);
}
public class Test05 {
public static void main(String[] args) {
useshow(new Intern() {
@Override
public void show() {
System.out.println("匿名内部类show..");
}
});
}
public static void useshow(Intern intern){
intern.show();
}
}
interface Intern{
void show();
}
public class Test06 {
public static void main(String[] args) {
useCalacutor((a,b)-> a+b);
}
public static void useCalacutor(Calacutor calculator){
int sum=calculator.sum(5,6);
System.out.println(sum);
}
}
@FunctionalInterface
interface Calacutor{
int sum(int a,int b);
}
方法引用
如果lambda需要做的事情在另一个类中已经存在了,可以直接拿过来替换lambda,这就叫方法引用
例如 :hireSitter(Cook::makeFood); 双冒号连接起来写是Java8引入的新特性,叫方法引用
目的:为简化lambda而存在
代替了接口
方法引用:类名引用静态方法
格式:类名::静态方法名
public class LambdaDemo {
public static void main(String[] args) {
hireSitter(sitter-> System.out.println("做好"+sitter));
hireSitter(Cook::makeFood);
method(Math::abs);
}
public static void hireSitter(Sitter sitter){
sitter.makeFood("司康");
}
public static void method(Calcutor calcutor){
int abs=calcutor.getAbs(-25);
System.out.println(abs);
}
}
@FunctionalInterface
interface Sitter{
void makeFood(String food);
}
class Cook{
public static void makeFood(String food){
System.out.println("做好了"+food);
}
}
interface Calcutor{
int getAbs(int num);
}
方法引用另一种格式:通过对象名引用成员方法,
格式: 对象名::成员方法名
public class Demo01 {
public static void main(String[] args) {
Cook cook=new Cook();
method(cook::makeFood);
}
public static void method(Sitter sitter){
sitter.work("土豆");
}
}
class Cook{
public void makeFood(String food){
System.out.println("做好了"+food);
}
}
interface Sitter{
void work(String food);
}
扩展
public class Demo02 {
public static void main(String[] args) {
useMonitor(System.out::println);
}
public static void useMonitor(Monitor monitor){
monitor.show("hello tz");
}
}
@FunctionalInterface
interface Monitor{
void show(String str);
}