- 一、抽象类
- 介绍
- 使用场景
- 语法
- 抽象类的注意事项和细节(注意: 1,5,8)
- 抽象类和普通类的区别
- 模板设计模式
- 介绍
- 案例
- 二、接口
- 基本介绍
- 接口使用的注意事项和使用细节(注意:4,6,8)
- 实现接口VS继承类
- 接口的多态特性
- 多态传递
- 接口和抽象类的区别
- 三、内部类(重点、难点)
- 基本介绍
- 内部类的分类
- 局部内部类
- 匿名内部类(重要!!!)
- 匿名内部类的使用
- 匿名内部类使用的注意事项和细节
- 匿名内部类的实践
- 成员内部类
- 静态内部类
- 不能被实例化,但可以作为父类引用指向子类对象
- 修饰符不能有private,final,static
- 如果有抽象方法抽象类一定要加上abstract
- 继承过程中抽象方法一定要被实现或者继续抽象
把通用的步骤放到抽象类的一个执行方法中,每个步骤定义成抽象方法,子类实现每个步骤的细节,当子类调用父类的执行方法时,如果遇到通用步骤就会调用子类的具体步骤来实现,(注意:新建对象时运行类型和编译类型都是子类的,只是调用了父类的方法而已,而通用步骤的方法子类对父类已经实现,所以调用的还是子类的)
案例package com.bijing.static_.abstract_; public abstract class Template { public static void main(String[] args) { AA aa = new AA(); BB bb = new BB(); aa.getTime(); bb.getTime(); } public void getTime() { long startTime = System.currentTimeMillis(); job(); long endTime = System.currentTimeMillis(); System.out.println("运行时间:" + (endTime - startTime)); } public abstract void job(); } class AA extends Template { @Override public void job() { long sum = 0; for (long i = 0; i < 100000; i++) { sum += i; } } } class BB extends Template { @Override public void job() { long sum = 0; for (long i = 0; i < 1000000; i++) { sum += i; } } }二、接口 基本介绍
注意:
- 在接口中抽象方法可以不加abstract
- jdk8及以后可以有默认方法但是要加default关键字,如果是静态方法不用加default
实现接口时对java单继承的补充
- 当子类继承了父类就自动拥有了父类的功能
- 如果子类需要拓展功能就需要通过实现接口的方式来拓展
有点类似向上转型和向下转型
多态传递//I3实现了I1,I1继承了I2,所以接口I1和I2都可以使用I3的实例 //或者说I3==>I1->I2,I1和I2都可以使用I3的实例 interface I1 extends I2 { } interface I2 { } class I3 implements I1 { } public class Test { public static void main(String[] args) { I1 i1 = new I3(); I2 i2 = new I3(); } }接口和抽象类的区别
- 接口是对动作的抽象,抽象类是对本质的抽象
- 接口中所有成员变量都是用public static final修饰的
- 接口中没有构造器,没有main方法,因为它不是一个类
- 抽象类是用来继承的(extends),接口是用来实现的(implements)
- 接口是多继承的,抽象类是单继承的
- 接口中声明默认方法要加default,静态方法可以不加
- 接口中可以有静态方法不能有静态代码块,抽象类中可以有静态方法和静态代码块
类的五大成员:属性,方法,构造器,代码块,内部类
内部类的分类 局部内部类
tips:因为在方法中,所以当成方法的一个局部变量,不过是以类的形式而存在的,所以可以访问外部类的成员但是不能添加访问修饰符,作用域也仅仅在定义它的方法或代码中,要使用也只能在方法中实例化对象
案例:
interface Plants { void say(); } class Animal { private String name; public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } void say() { System.out.println("我是动物" + getName()); } } public class LocalInnerClass { public static void main(String[] args) { LocalInnerClass localInnerClass = new LocalInnerClass(); localInnerClass.getAnimal(); localInnerClass.getPlants(); } //局部内部类--继承外部的一般类 void getAnimal() { class Pig extends Animal { public Pig(String name) { super(name); } } Animal animal = new Pig("猪"); animal.say(); } //局部内部类--实现外部的接口 void getPlants() { class Tree implements Plants { String name; public Tree(String name) { this.name = name; } @Override public void say() { System.out.println("我是植物" + this.name); } } Plants plants = new Tree("树"); plants.say(); }匿名内部类(重要!!!) 匿名内部类的使用
所谓的匿名实则是系统给的我们不知道而已,系统分配为***$1
//前提:必须继承一个父类或实现一个接口 interface Plants02 { String name = "apple tree"; void say(); } public class AnonymousInnerClass { int a = 1; String name = "pear tree"; public static void main(String[] args) { AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass(); anonymousInnerClass.getAnimal02(); anonymousInnerClass.getPlant02(); } //匿名内部类 void getAnimal02() { //继承类式的 Animal02 dog = new Animal02("二狗") { public void say() { int a = 10; System.out.println("我是" + getName()); System.out.println(a);//10 System.out.println(AnonymousInnerClass.this.a);//1 } public void sayName() { } }; dog.say(); // dog.sayName(),报错是因为dog的编译类型是Animal02,它没有sayName()方法 } void getPlant02() { //实现接口式的 Plants02 tree = new Plants02() { @Override public void say() { System.out.println("我是树"); System.out.println(name);//apple tree System.out.println(AnonymousInnerClass.this.name);//pear tree } }; tree.say(); //lambda表达式 Plants02 trees = () -> System.out.println("我是树"); } } class Animal02 { private String name; public Animal02(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } void say() { System.out.println("我是动物" + getName()); } }
注意和匿名对象的区别
//下面的运行类型是Tiger Animal animal2 = new Tiger(); //下面的运行类型是Outer$2 Animal animal3 = new Tiger() { };匿名内部类使用的注意事项和细节
tips:匿名内部类一般都是new 接口名/父类名 (){},创建出来的匿名内部类是“儿子”
public void f1() { //这边是类 Person p = new Person() { @Override public void hi() { System.out.println("内部hi() "); } }; p.hi(); //匿名内部类本身也是对象 new Person() { @Override public void hi() { System.out.println("新的内部hi() "); } }.hi(); }
和传统方法对比:
interface Plant { void show(); } public class Use_ { public static void main(String[] args) { //使用匿名内部类 f1(new Plant() { @Override public void show() { System.out.println("wo shi plant"); } }); //传统方法 f1(new Tree()); } public static void f1(Plant plant) { plant.show(); } } //传统方法 class Tree implements Plant { @Override public void show() { System.out.println("wo shi tree"); } }成员内部类
public class OuterClass { int a = 1; public static void main(String[] args) { //调用成员内部类方法 OuterClass outerClass = new OuterClass(); outerClass.useInnerClass(); //创建成员内部类对象,使用成员内部类属性,方法 OuterClass.InnerClass innerClass = outerClass.new InnerClass(); System.out.println(innerClass.name); innerClass.say(); } public void useInnerClass() { InnerClass innerClass = new InnerClass(); innerClass.say(); } class InnerClass { String name = "内部类"; int a = 10; void say() { System.out.println("我是内部类"); System.out.println(a);//10 System.out.println(OuterClass.this.a);//1 } } } class OtherOuterClass { public static void main(String[] args) { // 外部其他类中使用 OuterClass outerClass = new OuterClass(); outerClass.useInnerClass(); //创建成员内部类对象,使用成员内部类属性,方法 OuterClass.InnerClass innerClass = outerClass.new InnerClass(); System.out.println(innerClass.name); innerClass.say(); } }
第五点:
第六点:
class OuterClass { public InnerClass02 getInnerClass() { return new InnerClass02(); } class InnerClass { } class InnerClass02 { } } class Visit { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); //方式一 OuterClass.InnerClass innerClass = outerClass.new InnerClass(); //方式二 OuterClass.InnerClass02 innerClass02 = outerClass.getInnerClass(); } }静态内部类
public class StaticInnerClass { static int a = 1; public static void main(String[] args) { //静态内部类对象创建及使用 InnerClass innerClass = new InnerClass(); innerClass.say(); StaticInnerClass.InnerClass innerClass1 = new InnerClass(); innerClass1.say(); } static class InnerClass { int a = 10; void say() { System.out.println("我是静态内部类"); System.out.println(a);//10 System.out.println(StaticInnerClass.a);//1 } } } //在其他外部内中使用静态内部类 class OtherOuterClass_ { public static void main(String[] args) { StaticInnerClass.InnerClass innerClass = new StaticInnerClass.InnerClass(); innerClass.say(); } }