1 抽象类

1.1 抽象类引出



当一个类中存在抽象方法时,需要将该类声明为abstract
所谓抽象方法就是没有实现的方法(没有方法体)
一般来说,抽象类会被继承,有其子类来实现抽象方法.

package com.hspedu.abstract_;public class Abstract01 {public static void main(String[] args) {}
}abstract class Animal {private String name;public Animal(String name) {this.name = name;}//思考:这里eat 这里你实现了,其实没有什么意义//即: 父类方法不确定性的问题//===> 考虑将该方法设计为抽象(abstract)方法//===> 所谓抽象方法就是没有实现的方法//===> 所谓没有实现就是指,没有方法体//===> 当一个类中存在抽象方法时,需要将该类声明为abstract类//===> 一般来说,抽象类会被继承,有其子类来实现抽象方法.
//    public void eat() {
//        System.out.println("这是一个动物,但是不知道吃什么..");
//    }public abstract void eat()  ;
}

1.2 抽象类使用细节

1.2.1 抽象类使用细节1


package Abstract_;public class AbstractDetail01 {public static void main(String[] args) {//抽象类,不能被实例化//new A();}
}
//抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
//,还可以有实现的方法。
abstract class A {public void hi() {System.out.println("hi");}
}
//一旦类包含了abstract方法,则这个类必须声明为abstract,否则编译不会通过
abstract class B {public abstract void hi();
}
//abstract 只能修饰类和方法,不能修饰属性和其它的
class C {// public abstract int n1 = 1;
}

1.2.2 抽象类使用细节2

package Abstract_;public class AbstractDetail02 {public static void main(String[] args) {System.out.println("hello");}
}
//抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
abstract class H {public   abstract void hi();//抽象方法
}//如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
abstract class E {public abstract void hi();
}
abstract class F extends E {}
class G extends E {@Overridepublic void hi() { //这里相等于G子类实现了父类E的抽象方法,所谓实现方法,就是有方法体}
}//抽象类的本质还是类,所以可以有类的各种成员
abstract class D {public int n1 = 10;public static  String name = "你好";public void hi() {System.out.println("hi");}public abstract void hello();public static void ok() {System.out.println("ok");}
}

1.3 抽象类课堂练习

package com.hspedu.abstract_;abstract public class Employee {private String name;private int id;private double salary;public Employee(String name, int id, double salary) {this.name = name;this.id = id;this.salary = salary;}//将work做成一个抽象方法public abstract void work();public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}
}
========================================
package com.hspedu.abstract_;public class Manager extends Employee {private double bonus;public Manager(String name, int id, double salary) {super(name, id, salary);}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}@Overridepublic void work() {System.out.println("经理 " + getName() + " 工作中...");}
}
======================================================
package com.hspedu.abstract_;public class AbstractExercise01 {public static void main(String[] args) {//测试Manager jack = new Manager("jack", 999, 50000);jack.setBonus(8000);jack.work();CommonEmployee tom = new CommonEmployee("tom", 888, 20000);tom.work();}
}

1.4 抽象模板模式



package Abstract_;public class TestTemplate {public static void main(String[] args) {AA aa = new AA();aa.calculateTime();//这里需要}
}
======================================
package Abstract_;public class AA extends Template{//计算任务public void job(){//实现父类Template的抽象方法joblong num = 0;for (int i = 1;i <= 1000000;i++){num += i;}}
}
======================================
package Abstract_;abstract public class Template {//抽象类-模板设计模式public abstract void job();//抽象方法public void calculateTime(){//实现方法,调用job方法//得到开始的时间long start = System.currentTimeMillis();job();//动态绑定机制//得到结束的时间long end = System.currentTimeMillis();System.out.println("执行时间 " + (end - start));}
}

2 接口

2.1 接口快速入门


package interface_;public class Camera implements UsbInterface{//实现接口,实际上就是把接口的方法实现@Overridepublic void start() {System.out.println("相机开始工作");}@Overridepublic void stop() {System.out.println("相机停止工作");}
}
=====================================================================
package interface_;
//Phone类实现UsbInterface
//解释:①Phone类需要实现UsbInterface接口 规定/声明的方法
public class Phone implements UsbInterface{@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop() {System.out.println("手机停止工作");}
}
======================================================================
package interface_;public class Computer {//编写一个方法,计算机工作public void work(UsbInterface usbInterface){//通过接口调用方法usbInterface.start();usbInterface.stop();}
}
====================================================
package interface_;public interface UsbInterface {//接口//规定接口的相关方法,教师规定的,规范public void start();public void stop();}
======================================================
package interface_;public class Interface01 {public static void main(String[] args) {//创建手机,相机对象Camera camera = new Camera();Phone phone = new Phone();//创建计算机Computer computer = new Computer();computer.work(phone);//把手机接入到计算机System.out.println("==============");computer.work(camera);//把相机接入到计算机}
}

2.2 接口基本介绍

2.3 接口应用场景



2.4 接口使用细节

2.4.1 接口使用细节1

2.4.2 接口使用细节2

2.5 接口vs继承

package com.hspedu.interface_;public class ExtendsVsInterface {public static void main(String[] args) {LittleMonkey wuKong = new LittleMonkey("悟空");wuKong.climbing();wuKong.swimming();wuKong.flying();}
}//猴子
class Monkey {private String name;public Monkey(String name) {this.name = name;}public void climbing() {System.out.println(name + " 会爬树...");}public String getName() {return name;}
}//接口
interface Fishable {void swimming();
}
interface Birdable {void flying();
}//继承
//小结:  当子类继承了父类,就自动的拥有父类的功能
//      如果子类需要扩展功能,可以通过实现接口的方式扩展.
//      可以理解 实现接口 是 对java 单继承机制的一种补充.
class LittleMonkey extends Monkey implements Fishable,Birdable {public LittleMonkey(String name) {super(name);}@Overridepublic void swimming() {System.out.println(getName() + " 通过学习,可以像鱼儿一样游泳...");}@Overridepublic void flying() {System.out.println(getName() + " 通过学习,可以像鸟儿一样飞翔...");}
}

==小结: == 当子类继承了父类,就自动的拥有父类的功能
如果子类需要扩展功能,可以通过实现接口的方式扩展.
可以理解 实现接口 是 对java 单继承机制的一种补充.

2.6 接口多态传递

package interface_;public class InterfacePolyPass {//多态传递public static void main(String[] args) {//接口类型的变量可以指向,实现了该接口的类的对象实例IG ig = new Teacher();//如果IG继承了IH接口,而Teacher类实现了IG接口//那么实际上就相当于Teacher类也实现了IH接口IH ih = new Teacher();}
}
//接口
interface IH{ }
interface IG extends IH{ }
//实现了IG接口的类
class Teacher implements IG{ }

2.7 接口课堂练习


package interface_;public class InterfaceExercise02 {public static void main(String[] args) {}
}interface A {  // 1min 看看int x = 0;
}  //想到 等价 public static final int x = 0;class B {int x = 1;//普通属性
}class C extends B implements A {public void pX() {//System.out.println(x); //错误,原因不明确x//可以明确的指定x//访问接口的 x 就使用 A.x//访问父类的 x 就使用 super.xSystem.out.println(A.x + " " + super.x);//输出 0 1}public static void main(String[] args) {new C().pX();}
}

3 四种内部类

内部类:一个类的内部又完整地嵌套了另一个结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class).是我们类的第五大成员(属性、方法、构造器、代码块、内部类),内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
底层源码,有大量的内部类

基本语法:

package innerclass;public class InnerClass01 { //外部其他类public static void main(String[] args) {}
}
class Outer { //外部类private int n1 = 100;//属性public Outer(int n1) {//构造器this.n1 = n1;}public void m1() {//方法System.out.println("m1()");}{//代码块System.out.println("代码块...");}class Inner { //内部类, 在Outer类的内部}
}

3.1 局部内部类

局部内部类是定义在外部类的局部位置,比如方法中(代码块中),并且有类名
1.可以直接访问外部类的所有成员,包括私有的;
2.不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的,但是可以用final修饰,因为局部变量也可以使用final
3.作用域:仅仅定义在它的方法或者代码块中。
4.局部内部类–访问–》外部类的成员[访问方式:直接访问]
5.外部类–访问–》局部内部类的成员
访问方式:创建对象,再访问(必须在作用域中)

package innerclass;
/*** 演示局部内部类的使用*/
public class LocalInnerClass {//public static void main(String[] args) {//演示一遍Outer02 outer02 = new Outer02();outer02.m1();System.out.println("outer02的hashcode=" + outer02);}
}
class Outer02 {//外部类private int n1 = 100;private void m2() {System.out.println("Outer02 m2()");}//私有方法public void m1() {//方法//1.局部内部类是定义在外部类的局部位置,通常在方法//3.不能添加访问修饰符,但是可以使用final 修饰//4.作用域 : 仅仅在定义它的方法或代码块中final class Inner02 {//局部内部类(本质仍然是一个类)//2.可以直接访问外部类的所有成员,包含私有的private int n1 = 800;public void f1() {//5. 局部内部类可以直接访问外部类的成员,比如下面 外部类n1 和 m2()//7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,//   使用 (外部类名.this.成员)去访问//   Outer02.this 本质就是外部类的对象, 即哪个对象调用了m1, Outer02.this就是哪个对象System.out.println("n1=" + n1 + " 外部类的n1=" + Outer02.this.n1);System.out.println("Outer02.this hashcode=" + Outer02.this);m2();}}//6. 外部类在方法中,可以创建Inner02对象,然后调用方法即可Inner02 inner02 = new Inner02();inner02.f1();}
}

3.2 匿名内部类

(最重要!)
匿名内部类:
1.本质是类
2.内部类
3.该类没有名字(但其实它是有名字的,是系统给分配的,底层可以查,我们看不到)
4.同时它还是一个对象
**说明:**匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

3.2.1匿名内部类的基本语法

package innerclass;
/*** 演示匿名内部类的使用*/
public class AnonymousInnerClass {//外部其他类public static void main(String[] args) {Outer04 outer04 = new Outer04();outer04.method();}
}
class Outer04 { //外部类private int n1 = 10;//属性public void method() {//方法//基于接口的匿名内部类//1.需求: 想使用IA接口,并创建对象//2.传统方式:写一个类,实现该接口,并创建对象//3.需求是 Tiger/Dog 类只是使用一次,后面再不使用//4. 可以使用匿名内部类来简化开发//5. tiger的编译类型 ? IA//6. tiger的运行类型 ? 是匿名内部类  Outer04$1/*我们看底层 会分配 类名 Outer04$1class Outer04$1 implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}}*///7. jdk底层在创建匿名内部类 Outer04$1,立即就创建了 Outer04$1实例,// 并且把地址返回给tiger//8. 匿名内部类使用一次,就不能再使用IA tiger = new IA() {@Overridepublic void cry() {System.out.println("老虎叫唤...");}};System.out.println("tiger的运行类型=" + tiger.getClass());tiger.cry();tiger.cry();tiger.cry();//        IA tiger1 = new Tiger();//传统方式,接口类型可以指向实现了该接口的类的对象实例
//        tiger1.cry();//演示基于类的匿名内部类//分析//1. father编译类型 Father//2. father运行类型 Outer04$2//3. 底层会创建匿名内部类/*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}}*///4. 同时也直接返回了匿名内部类 Outer04$2的对象//5. 注意("jack") 参数列表会传递给 构造器Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了test方法");}};System.out.println("father对象的运行类型=" + father.getClass());//Outer04$2father.test();//基于抽象类的匿名内部类Animal animal = new Animal(){@Overridevoid eat() {System.out.println("小狗吃骨头...");}//必须重写实现};animal.eat();}
}
interface IA {//接口public void cry();
}
class Tiger implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}
}
//class Dog implements  IA{
//    @Override
//    public void cry() {
//        System.out.println("小狗汪汪...");
//    }
//}class Father {//类public Father(String name) {//构造器System.out.println("接收到name=" + name);}public void test() {//方法}
}
abstract class Animal { //抽象类abstract void eat();//抽象方法
}

3.2.2 匿名内部类的使用

匿名内部类的语法比较奇特,匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上来看,它既有定义类的特征,也有创建对象的特征,对前面的代码分析可以看出这个特点,因此可以调用匿名内部类方法。

package innerclass;
//匿名内部类的语法比较特别,匿名内部类既是
public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();}
}
class Outer05{private int n1 = 99;public void f1(){//创建一个基于类的匿名内部类Person p= new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi方法");}};p.hi();//编译类型是Person,所以能调用hi();// 根据动态绑定,// 因为真正的运行类型是Outer05$1,所以运行时输出的是’ 匿名内部类重写了hi方法‘//也可以直接调用//class 匿名内部类 extends Person{}new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi()方法。。。");}@Overridepublic void ok(String str) {super.ok(str);//父类是Person,即super会调Person}}.ok("jack");}
}class Person{//类public void hi(){System.out.println("Person hi()");}public void ok(String str){System.out.println("Person ok() + str");}
}

1.可以直接访问外部类的所有成员,包括私有的;
2.不能添加访问修饰符,因为它的地位就是一个局部变量
3.作用域:仅仅定义在它的方法或者代码块中。
4.外部其他类——>不能访问——>匿名内部类(因为 匿名内部类地位是一个局部变量)
5.如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认就近原则;
如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

package innerclass;
//匿名内部类的语法比较特别,匿名内部类既是
public class AnonymousInnerClassDetail {public static void main(String[] args) {Outer05 outer05 = new Outer05();outer05.f1();System.out.println("main 方法中Outer05.this hashcode=" + outer05);}
}
class Outer05{private int n1 = 99;public void f1(){//创建一个基于类的匿名内部类Person p= new Person(){private int n1 = 88;@Overridepublic void hi() {System.out.println("匿名内部类重写了hi方法;");System.out.println("n1=" + n1 + " 外部类的n1=" + Outer05.this.n1);//Outer05.this 就是调用f1的对象System.out.println("Outer05.this hashcode=" + Outer05.this);}};p.hi();//编译类型是Person,所以能调用hi();// 根据动态绑定,// 因为真正的运行类型是Outer05$1,所以运行时输出的是’ 匿名内部类重写了hi方法‘//也可以直接调用//class 匿名内部类 extends Person{}new Person(){@Overridepublic void hi() {System.out.println("匿名内部类重写了hi()方法。。。");}@Overridepublic void ok(String str) {super.ok(str);//父类是Person,即super会调Person}}.ok("jack");}
}class Person{//类public void hi(){System.out.println("Person hi()");}public void ok(String str){System.out.println("Person ok() + str");}
}

3.2.3匿名内部类实践

最佳实践:当作实参直接传递,简洁高效。

package innerclass;public class InnerClassExercise01 {public static void main(String[] args) {//当作实参直接传递,简洁高效f1(new IL() {@Overridepublic void show() {System.out.println("这是一幅名画...");}});//传统方法f1(new Picture());}//静态方法,形参时接口类型public static void f1(IL il){il.show();}
}
//接口
interface IL{void show();
}
//类->实现IL=》编程领域,称作硬编码
class Picture implements IL{@Overridepublic void show() {System.out.println("这是一幅名画...");}
}

3.3 成员内部类

package innerclass;public class InnerClass01 {public static void main(String[] args) {Outer08 outer08 = new Outer08();outer08.t1();}
}class Outer08{private int n1 = 10;public String name = "张三";//成员内部类是定义在外部类的成员位置上protected class Inner08{//成员内部类public void say(){//可以直接访问外部类的所有成员,包含私有的System.out.println("Outer01的 n1 =" + n1 + "outer01的name=" + name);}}//写方法public void t1(){//使用了成员内部类Inner08 inner08 = new Inner08();inner08.say();}
}


外部其他类—>访问---->成员内部类

package innerclass;public class InnerClass01 {public static void main(String[] args) {Outer08 outer08 = new Outer08();//外部其他类,使用成员内部类的两种方式//方法一://outer08.new Inner08();就相当于把new Inner08()当作是outer08成员// 就是一个语法,不用纠结Outer08.Inner08 inner08 = outer08.new Inner08();//方法二://在外部类中,编写一个方法,可以返回Inner08对象Outer08.Inner08 inner08Instance = outer08.getInner08Instance();inner08Instance.say();}
}class Outer08{private int n1 = 10;public String name = "张三";//成员内部类是定义在外部类的成员位置上protected class Inner08{//成员内部类public void say(){//可以直接访问外部类的所有成员,包含私有的System.out.println("Outer01的 n1 =" + n1 + "outer01的name=" + name);}}public Inner08 getInner08Instance(){//该方法返回Inner08的实例return new Inner08();}
}


外部类和内部类成员重名,内部类访问,默认遵循就近原则;
如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

3.4 静态内部类


package innerclass;public class StaticInnerClass01 {public static void main(String[] args) {Outer10 outer10 = new Outer10();outer10.m1();}
}
class Outer10{private int n1 = 10;private static String name = "jungle";//Inner10就是静态内部类//1.放在外部类的成员位置//2.使用static修饰//3.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员//4.可以添加任意访问修饰符(public/protected/默认/private),因为它的地位就是一个成员//5.作用域:同其他成员,为整个类体private static class Inner10{public void say(){System.out.println(name);}}public void m1(){Inner10 inner10 = new Inner10();inner10.say();}}


外部其他类访问静态内部类:

package innerclass;public class StaticInnerClass01 {public static void main(String[] args) {Outer10 outer10 = new Outer10();//外部其他类访问静态内部类//方式一://因为静态内部类,是可以通过类名直接访问,前提是满足访问权限Outer10.Inner10 inner10 = new Outer10.Inner10();inner10.say();//方式二;//编写一个方法,可以返回静态内部类的对象实例Outer10.Inner10 inner101 = outer10.getInner10();//方法三://写一个静态方法,可以用类名直接引用Outer10.Inner10 inner10_ = Outer10.getInner10_();inner10_.say();}
}
class Outer10{private static String name = "jungle";static class Inner10{public void say(){System.out.println(name);}}public Inner10 getInner10(){return new Inner10();}public static Inner10 getInner10_(){return new Inner10();}}


静态不用加this

4 小结

①内部类有四种,局部内部类,匿名内部类,成员内部类,静态内部类
②重点是匿名内部类的使用
new 类/接口(参数列表){
//…
}
③成员内部类、静态内部类是放在外部类的成员位置,本质就是一个成员

Java基础 DAY17相关推荐

  1. Java基础day17

    Java基础day17 Java基础day17-File&递归&字节流 1.File类 1.1File类概述和构造方法 1.2File类创建功能 1.3File类判断和获取功能 1.4 ...

  2. 视频教程-清华-尹成老师-java基础-Day17-Java

    清华-尹成老师-java基础-Day17 毕业于清华大学,曾担任Google算法工程师,微软人工智能领域全球最具价值专家,微软Tech Ed 大会金牌讲师. 精通C/ C++,Python ,Go语言 ...

  3. java基础学习_IO流03_字符流、IO流小结、案例_day21总结

    java基础学习_IO流03_字符流.IO流小结.案例_day21总结 ================================================================ ...

  4. Java基础入门语法和安装

    1. Java概述 1.1 Java语言背景介绍(了解) 语言:人与人交流沟通的表达方式 计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言 Java语言是美国Sun公司(Stanford Un ...

  5. Java笔记整理-02.Java基础语法

    1,标识符 由英文字母.数字._(下划线)和$组成,长度不限.其中英文字母包含大写字母(A-Z)和小写字母(a-z),数字包含0到9. 标识符的第一个字符不能是数字(即标识符不能以数字开头). 标识符 ...

  6. java基础(十三)-----详解内部类——Java高级开发必须懂的

    java基础(十三)-----详解内部类--Java高级开发必须懂的 目录 为什么要使用内部类 内部类基础 静态内部类 成员内部类 成员内部类的对象创建 继承成员内部类 局部内部类 推荐博客 匿名内部 ...

  7. Java基础概念性的知识总结

    属于个人的所学的知识总结,不是全面的 1.JDK.JRE和JVM三者的区别 01.JDK:(Java Development ToolKit)Java开发工具包,是整个Java的核心.包括了Java的 ...

  8. 我的面试标准:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架!...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:hsm_computer www.cnblogs.com/J ...

  9. 叮!您收到一份超值Java基础入门资料!

    摘要:Java语言有什么特点?如何最大效率的学习?深浅拷贝到底有何区别?阿里巴巴高级开发工程师为大家带来Java系统解读,带你掌握Java技术要领,突破重点难点,入门面向对象编程,以详细示例带领大家J ...

最新文章

  1. JAVAC 命令详解 -d表示目录
  2. 如何造出逼真图像?南洋理工Zheng博士论文《基于深度生成学习的逼真图像合成》197页pdf阐述视觉合成工作...
  3. rootkit 检测报告
  4. 【成都站参会指南】神策 2020 数据驱动用户大会,邀您面基!
  5. The Preliminary Contest for ICPC China Nanchang National Invitational
  6. Oracle中的Raw类型解释
  7. 超级日志服务器-Splunk
  8. 域内操作主机角色一向让很多人很头痛,我归纳总结一下,希望对大家有帮助...
  9. 基于matlab的数字下变频器的设计与仿真应用,基于MATLAB的数字下变频器的没汁与仿真应用...
  10. 追MM与设计模式的有趣见解
  11. swift int转string_用Swift开发macOS程序,九、目录模块
  12. Windows10下python3.5的sklearn库安装
  13. linux raid5卷,Linux逻辑卷及RAID5的创建
  14. 数据结构基本操作_【算法与数据结构 03】数据处理的基本操作——增删查
  15. Office Visio 2007 简体中文版资源下载及安装教程
  16. shell脚本定时重启tomcat
  17. dog log 算子_灰度图像--图像分割 Marr-Hildreth算子(LoG算子)
  18. 关于Bundle Adjustment(BA)的直观理解
  19. 高数笔记(十七):二重积分的概念、性质与计算,三重积分的概念、性质与计算
  20. 常见的状态码HTTP Status Code

热门文章

  1. 环境配置 | 更改注册表使PPT导出的图片分辨率达到300dpi
  2. 物联网卡的使用规则,用物联卡的朋友注意了!
  3. card_list_operation.erl
  4. numpy 学习汇总5-数组运算 tcy
  5. Codeforces Round #180 (Div. 2) B. Sail 【模拟】
  6. 【R-FCN】《R-FCN: Object Detection via Region-based Fully Convolutional Networks》
  7. LeetCode70. 爬楼梯(Java解法——使用完全背包求解)
  8. 解析 float : left
  9. 艰难的一年!2021年计算机考研年度总结!
  10. 【时间序列】python与时间序列基本教程4(超过1.9万字 代码超过900行 包括49个图)...