天气晴朗,阳光明媚,学习算法,做作业。
昨天晚上用java 语言做算法作业关于 人-位置 匹配 : 医院和医学院学生配对。 结果被 Dictionary、Enumeration 、Hashtable、HashMap 、Map之间的 关系搞得晕头转向。我不过是想用个字典的数据结构去保存 医院对学生的邀请记录,然后遍历出来罢了, 结果网上五花八方的 代码。 最头痛的是,编译的时候 还老报 找不到符号 的错误。
为了后面的算法作业能够顺利地用java 写完,索性今天就来搞清楚它们之间的关系!
截图来自:https://www.runoob.com/java/java-map-interface.html
接口:关键字 interface,只定义方法名
对上:接口可以 extends 多个 接口类
对下:可以被接口继承extends,被抽象类、实类 实现 implements
这里先定义一个接口方法 method1,一会用来被抽象类实现
public interface Api {
public String method1();
抽象类:关键字 abstract,也可以只写方法名,想写点具体的方法代码也行,只是不给直接用
对上:抽象类只能extends一个抽象类、实体类,可以 implements 多个接口
对下:抽象类只能被抽象类、实体类继承 extends 不能被实例化 new , 方法只能被继承了它的类使用
这里定义一个抽象类,写个构造函数,实现接口方法,再重载一下接口方法(方法名不变,增加一个方法参数),然后用来被实体类继承。
public abstract class Abs implements Api {
public Abs() {
System.out.println("\n constructor Abs:来自abstract abs constructor Abs");
public String method1() {
System.out.println("abstract method1:来自abstract abs method1");
return "methods->abs->api";
public String method1(String str1) {
System.out.println("abstract method1:来自abstract abs method1 : 重写,一个参数");
return "methods->abs->api";
实体类:关键字 class ,就是用来继承别的类,实现接口,写自己的方法的类。这下里面的方法都可以用,还可以霍霍被继承来的方法(重写->多态)。
对上:实体类只能extends一个抽象类、实体类,可以 implements 多个接口
对下:实体类只能被抽象类、实体类继承 extends 可以实例化 new
这里定义一个实体类,用来继承抽象类,并实现接口api ,写个构造函数,重写method1, 重载method1为两个参数.
(备注:这里虽然,也写了要实现接口Api,但因为继承的抽象类里面有实现过api的方法,所以实际该实体类可以什么方法都不写,不会报错。具体判断有没有实现接口方法,似乎是在整个继承链路上去找该接口方法是否存在)
public class RealParent extends Abs implements Api {
RealParent() {
System.out.println("constructor RealParent:class RealParent extends Abs constructor RealParent");
@Override
public String method1() {
System.out.println("RealParent method1:class RealParent extends Abs method1 方法,调用父类");
return super.method1();
public String method1(String self1, String self2) {
System.out
.println("RealParent method1:class RealParent extends Abs method1 方法, overWrite. 两个参数"+self1+self2);
return "methods->Real->Abs->api";
子类:继承了别的实体类 的类
写个构造函数,重写被继承来的method1,重写两个参数的method1方法,重载method1 为三个参数
public class Real extends RealParent {
Real() {
System.out.println("constructor Real:class Real extends RealParent constructor Real");
@Override
public String method1() {
System.out.println("Real method1:class Real extends RealParent method1 方法,调用父类");
return super.method1();
@Override
public String method1(String self1, String self2) {
System.out.println("Real method1:class Real extends RealParent method1 方法, overWrite. 两个参数" +self1+self2);
return "methods->Real->RealParent->Abs->api";
public String method1(String self1, String self2, String self3) {
System.out
.println("Real method1:class Real extends RealParent method1 方法, overWrite. 三个参数" +self1+self2+self3);
return "methods->Real->RealParent->Abs->api";
这里开始观察,用 上面定义好的 接口、抽象类、实体类、子类 分别声明 一个 变量;
统一new 一个 Real类 赋值给这个变量;
分别调用这个变量的 method1 方法:无参数、一个参数、2个参数、3个参数,
看会发生什么?
结果1: 下面被注释掉的 方法调用,都是因为会报错 not applicable 的错误, 在申明的类中,这个方法不适用!
这个声明的类 可以起到过滤 赋值类的方法的作用!
public class App{
public static void main(String[] args) {
Real r = new Real();
System.out.println("main: 实例化Real,调用method1方法 Real类型");
System.out.println(r.method1());
System.out.println(r.method1("haha Real,一个参数"));
System.out.println(r.method1("haha Real","两个参数"));
System.out.println(r.method1("haha Real","两个参数","三个参数"));
Api r2 = new Real();
System.out.println("main: 实例化Real,调用method1方法 Api类型");
System.out.println(r2.method1());
Abs r3 = new Real();
System.out.println("main: 实例化Real,调用method1方法 Abs类型");
System.out.println(r3.method1());
System.out.println(r3.method1("haha Abs,传入一个参数"));
RealParent r4 = new Real();
System.out.println("main: 实例化Real,调用method1方法 RealParent类型");
System.out.println(r4.method1());
System.out.println(r4.method1("haha RealParent,传入一个参数"));
System.out.println(r4.method1("haha RealParent"," 传入两个参数"));
javac -encoding utf-8 *.java
java App >> App.txt
来看看,都输入了什么,观察一下方法的调用顺序:
constructor Abs:来自abstract abs constructor Abs
constructor RealParent:class RealParent extends Abs constructor RealParent
constructor Real:class Real extends RealParent constructor Real
main: 实例化Real,调用method1方法 Real类型
Real method1:class Real extends RealParent method1 方法,调用父类
RealParent method1:class RealParent extends Abs method1 方法,调用父类
abstract method1:来自abstract abs method1
methods->abs->api
abstract method1:来自abstract abs method1 : 重载,一个参数
methods->abs->api
Real method1:class Real extends RealParent method1 方法, overWrite. 两个参数haha Real两个参数
methods->Real->RealParent->Abs->api
Real method1:class Real extends RealParent method1 方法, overWrite. 三个参数haha Real两个参数三个参数
methods->Real->RealParent->Abs->api
上面只放了 实例r 输出的结果:
通过结果可以知道:代码的执行顺序:
抽象类constructor -> 实体类constructor ->子类constructor -> main 中的输出 ->
{ 零个参数的Method1方法 real中重写后的Real method1()->super中调用 RealParent method1() 重写-> super 中调用abstract method1 } ->
带一个参数的Method1方法,Real 中没有,RealParent中没有,Abs 中有,调用abstract method1 ->
带两个参数的Method1方法,Real中有,RealParent有,Real 重写了 RealParent两个参数的方法,所以调用 Real method1 ->
带三个参数的Method1方法,Real中有,其他没有,调用Real method1。
总结:
1、 new 一个实例化对象时,会从继承链的 最底层 构造函数依次向上外执行 。
2、执行方法时会从外向内找符合 方法名、参数名的 方法调用,直到找到后就执行。
初始化 4 种类型(real、Api、Abs、RealParent )的 r ,并用实例化后的Real 对象去赋值
既 在java中存在 以下四种 变量声明的形式:
1、 类 变量 = new 类名()
2、 接口 变量 = new 类名()
3、 抽象类 变量 = new 类名()
4、 父类 变量 = new 类名()
Real r = new Real();
Api r2 = new Real();
Abs r3 = new Real();
RealParent r4 = new Real();
当声明的类型typeA 和 赋值实例化的类型type B 不一致时,
两种类型的继承链路上的方法集合 存在以下关系:
若A∈B 则可以使用以下声明以及初始化语句,否则会报不兼容的错误。
typeA 变量c = new typeB();
实体对象 可访问的方法数量 = A∩B = A
实体对象 不可访问的方法数量 = A在B中的相对补集 = ∁UA
哦,终于搞清楚了 java 中的 神出鬼没的 接口 和 抽象类 。
看过java的数据结构后,还是觉得 前端的 对象 最好用,虽然java 中提供多种数据结构,但是方法未免也太多了。
看完 JavaScript 描述版本的 《数据结构与算法》 后觉得 光靠 Array 和 Object 就能实现大部分 的数据结构。
然而… 目前为止学习的过程中已经出现 Pascal、C++、java、python…
在java中存在 以下四种 变量声明的形式: 1、 类 变量 = new 类名() 2、 接口 变量 = new 类名() 3、 抽象类 变量 = new 类名() 4、 父类 变量 = new 类名()声明类型可以起到精简 方法数量的作用。来来里,一起熟悉下方法的调用顺序以及 报错的表现形式
定义 :指描述可属于任何类或结构的一组相关功能。
接口的成员可以是方法(不能有方法体),属性,事件和索引器,但不能包含常数,字段,运算符,实例构造函数析构函数或类,也不能包括任何种类的静态成员,接口中的成员不允许添加访问修饰符,(默认都是public)
1. 接口是一个引用类型,通过接口可以实现多重继承。
2. C#中接口的成员不能有new、public、protected、internal、private等修饰符。
3. 接口中只能声明”抽象”成员(所以不能直接下一步对接口进行
rect = RectangleImpl(5, 10)
print("长方形的面积为:", rect.area())
print("长方形的周长为:", rect.perimeter())
这段代码定义了一个抽象类 `Rectangle`,其中声明了两个抽象方法 `area` 和 `perimeter`,分别用于计算长方形的面积和周长。然后定义了一个实现类 `RectangleImpl`,该类继承了 `Rectangle` 抽象类,并实现了其中的两个抽象方法。最后,我们可以创建一个 `RectangleImpl` 的实例,并调用其 `area` 和 `perimeter` 方法来计算长方形的面积和周长。
nodejs 下使用js封装console.log方法输出自定义的彩色字体,遇到Octal escape sequences are not allowed in template strings
weixin_41899459:
nodejs 下使用js封装console.log方法输出自定义的彩色字体,遇到Octal escape sequences are not allowed in template strings
TypeScript是什么?TypeScript入门,第四遍学习——拨开TypeScript掀开过又关上的面纱(* ̄rǒ ̄)
window10 64系统中node-gyp的环境配置,为了在nodejs环境下访问sqlserver而用node-gyp,从热情到放弃系列