Java面向对象编程

- 数据类型

  • 基本数据类型:byte(位),short(短整数),int(整数),long(长整数),float(单精度),double(双精度),char(字符),boolean(布尔值)

- 数组

  • 数组排序:java.util.Array.sort(data);
  • 数组复制:System.arraycopy(原数组,原数组起始点,目标数组,目标数组起始点,拷贝长度)

- 数据库中表和Java类之间的关系

  • 数据实体表的定义 = 类的定义;
  • 表中的字段 = 类的成员属性;
  • 表的一行记录 = 类的一个实例化对象;
  • 表的多行记录 = 对象数组;
  • 表的外键关联 = 引用关联;

- 数据表与java类之间的映射的解决步骤

  • 先抛开所有的关联字段不看,写出类的基本组成
  • 通过引用配置关联字段的关系

- String类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- 字符串比较:
'==':进行数值比较,如果内存空间不一样,就无法准确比较
'equals()'只比较内容,建议将字符串常量写在equals()之前,匿名对象为空不会出现异常,否则会出现空指向
- tocharArray(): 将字符串转换为字符数组
- chatAt(int i): 返回字符串对应位置的字符
- String('字符数组',[start,end]):将字符数组转换为字符串,「可截段转换」
- getBytes(String s):将字符串转换为字节数组/编码转换
- equals(String s):字符串比较,区分大小子写
- equalsIgnocase(String s):不区分大小写比较
- compareTo(String s):进行字符串大小写比较
- compareIgnocase(String s):进行字符串不区分大小写的比较
- contains(String s):判断字符串是否存在
- indexOf(String s):从头查找字符串的位置
- indexOf(String str,int fromIndex):从指定位置查找字符串的位置
- lastIndexOf(String str):由后向前查找指定字符串的位置
- lastIndexOf(String str,int fromIndex):从指定未知有后向前查找指定字符串
- startsWith(String prefix):判断是否是以指定字符串开头
- startsWith(String prefix,int toffset):由指定位置判断是否以指定字符串开始
- endsWith(String suffix):判断是否以指定字符串结束
- replace(String s):字符串替换
- split():字符串截取,返回值用字符串数组接受
- substring():字符串截取
- format():字符串格式化操作
- concat(String s):字符串连接
- inrern():字符串入池
- isEmpty():判断字符串是否为空
- length():计算字符串的长度
- trim():删除开始空格
- toUpperCase():字母转大写(可以忽略非字母)
- toLowerCase():字母转小写

- 继承

继承的规则:

  • 不能多重继承,可以多层继承,层次不建议超过3层
  • 父类需要有无参构造
  • super()放在派生构造类的首行,表示子类调用父类构造的语句,在父类没有无参构造时,子类需要用super()明确调用有参构造
  • 派生类实例化对象时,会首先实例化父类对象,目的是为了给所有属性进行空间分配
  • 子类可以继承父类的一切,但是对于父类私有的属性,只能通过方法间接访问,不能直接访问

复写:

  • 子类定义了与父类方法名称相同,参数类型和个数完全相同的方法,就是方法的复写
  • 在子类复写父类的情况下,可以通过Super.方法名,调用已经被重写的父类方法
  • 子类复写的方法,不能拥有比父类更为严格的访问控制权限public>default>private
  • 父类private定义的方法不能被复写

属性覆盖:

  • 子类定义了一个和父类名称相同的属性名

final:终结器

  • 定义不能被继承的类
  • 定义不能被复写的方法
  • 定义不能被修改的常量

override和overloading的区别:

  • overloading:重载 概念:方法名称相同,参数的类型及个数不同 权限:无限制 ,在进行方法重载的时候并未对返回值做出限制
  • override:重写/复写 概念:方法名相同,参数类型及个数,返回值相同 权限:被覆写方法不能拥有更严格的控制权限

- 多态

  • 对象向上转型:创建一个子类对象,把它当作父类来看待,向上转型一定是安全的,但是一旦发生向上转型为父类对象,就不能调用子类原本特有方法
  • 对象向下转型:是子类向上转型的还原,也就是将父类对戏那个还原为本来的子类对象
  • instanceof:安全向下转型的测试

- Object类

  • object类是所有类的父类
  • 子类可以通过重写Object的toString方法来实现对象信息的输出
  • 对象比较:可以通过重写equals方法,指定规则比较

- 抽象类的定义与使用

  • 定义:用abstract来修饰的类,抽象类的主要作用在于对子类中覆写方法进行约定,抽象类中必然有抽象方法,抽象方法是用abstract修饰的没有方法体 的方法

  • 抽象类不是完整的类,不能实例化,若想使用抽象类则

    > 抽象类必须提供有子类,子类使用extends继承一个抽象类

    > 抽象的子类(不是抽象类)一定要重写抽象类中的全部抽象方法

    > 抽象类的实例化可以利用对象多态性通过子类向上转型的方式完成

  • 使用抽象类:

    > 抽象类中可以提供构造方法,但是抽象类无法直接实例化,须由子类的完成实例化操作

    > 抽象类中可以没有抽象方法,但是有抽象方法的类,必然是抽象类,须由abstract修饰

    > 抽象类之中主要目的是进行过度操作使用,所以当你要使用抽象类进行开发的时候,往往都是在你设计中需要解决继承问题时所带来的代码重复处理

    > 抽象类可以有static静态方法,该方法不受抽象类影响

    > 抽象类本质是加强型的类,可以描述一切的有关的现实事物,因此抽象类的设计应该是比类更高一层的定义

- 包装类

  • 对象型包装类(Object的直接子类):Boolean,Character
  • 数值型的包装类(Number的直接子类):Byte,Short,Integer,Long,Float,Double

Number类中的方法:

  • byteValue():从包装类中获取byte数据
  • shortValue():从包装类中获取short数据
  • intValue():从包装类中获取int数据
  • longValue():从包装类中获取long数据
  • floatValue():从包装类中获取float数据
  • doubleValue():从包装类中获取double数据

装箱与拆箱操作:

  • Interger类:Interger(int value)
  • Double类:Double(double value)
  • Boolean类:Boolean(boolean value)

- 接口(interface)

抽象类与普通类相比最大的优势在于:可以实现对子类覆写方法的控制,但在抽象类里面可能依然会保留有一些普通方法,而普通方法里面可能会涉及到一些安全或隐私的操作问题,那么这样在进行开发的过程之中,如果要想对外部隐藏全部的隐藏细节,则就可以通过接口来进行描述

接口可以理解为最纯粹的抽象类(最原始的定义接口之中是只包含抽象方法全局常量

  • 接口需要被子类实现,一个子类可以实现多个接口
  • 子类(如果不是抽象类)那么一定要覆写接口中的全部抽象方法
  • 接口对象可以利用子类对象的向上转型进行实例化
  • 接口虽然可以成功定义,但是在实际开发中,实现接口的可能是抽象类,一个抽象类可以实现多个接口,一个普通类可以继承一个抽象类,并且可以实现多个父接口,但是要求先继承后实现
  • 虽然接口无法继承一个父类,但是一个接口却可以继承多个父接口,此时称接口的多继承

在实际开发中,接口的使用有三种形式:

  • 进行标准设置
  • 表示一种操作的能力
  • 暴露远程方法视图

- 泛型

泛型就是参数化类型

  • 适用于多种数据类型执行相同的代码
  • 泛型的类型在指定时使用

优点:使用泛型时,在实际应用之前类型就已经确定了,不需要强制转换

使用范围:

  • 主要使用在集合中
  • 泛型类:只能用在成员变量上,只能使用引用类型
  • 泛型接口:只能用在抽象方法上
  • 泛型方法:返回值前加&ItT&gt

泛型的继承(?是通配符):

  • extends(上限):指定的类必须继承某个类,或实现某个接口(不是implements),即? extends List
  • super(下限):? extends List

- 常见包

  • java.lang:String,Number,Object等类,自动导入
  • java.lang.reflect:反射机制处理包,所有设计从此开始
  • java.util:工具类的定义,包括数据结构的定义
  • java.io:输入输出流操作的程序包
  • java.net:网络程序开发包
  • java.sql:数据库编程的开发包
  • java.applet:Java的最原始的使用形式,直接嵌套在网页上执行的程序类
  • 现在的程序以Application为主(有主方法的程序)
  • java.awt,java.swing:Java的图形界面开发包(GUI),其中awt是属于重量级组件,而swing是轻量级组件

- 生成jar文件

  • 对程序打包编译:javac -d Message.java;

  • 此时会形成cn包,包里面有相应的子包与*.class 文件,将其打包为mldn.jar

  • jar -cvf mldn.jar cn

    “-c”: 创建一个新的jar文件

    “-v”:得到一个详细输出

    “-f”:设置要生成的jar文件的名称,本初定义的是”mldn.jar”

  • set calsspath=.;jar包存在路径

- 访问权限

No. 访问范围 private default protected public
1 同包同类 y y y y
2 同包不同类 y y y
3 不同包的子类 y y
4 不同包的所有类 y

- UML图形

  • 类图:显示模型的静态结构,反应类内部结构以及其与其他类之间的关系

    >类名称

    >属性

    >方法

  • 时序图:反应代码的执行流程

  • 用例图:描述程序的执行分配

- 设计模式

控制实例化产生个数的设计操作

  • 单例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    //饿汉式
    class Singleton{
    private static final Singleton INSTANCE=new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
    if(instance==null){
    instance=new Singleton();
    }
    return instance;
    }
    public void print(){
    System.out.println("www.mldn.cn");
    }
    }
    public class JavaDemo{
    public static void main(String args[]) {
    Singleton instance=null;
    instance=Singleton.getInstance();
    instance.print();
    }
    }
    //懒汉式
    class Singleton{
    private static Singleton instance=new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
    return instance;
    }
    public void print(){
    System.out.println("www.mldn.cn");
    }
    }
    public class JavaDemo{
    public static void main(String args[]) {
    Singleton instance=null;
    instance=Singleton.getInstance();
    instance.print();
    }
    }
  • Singleton程序的特点

    >代码如上,可以将懒汉式和饿汉式都写上;

    >特点:构造方法私有化,类内部提供static 方法获取实例化对象,不管外部如何操作,永远只有一个实例化提供

  • 多例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Color{
    private static final Color RED=new Color("红色");
    private static final Color Green=new Color("绿色");
    private static final Color Blue=new Color("蓝色");

    private String title;
    private Color(String title) {
    this.title=title;
    }
    public static Color getInstance(String color){
    switch(color){
    case "red":return RED;
    case "green":return GREEN;
    case "blue":return BLUE;
    default:return null;
    }
    }
    public String toString(){
    return this.title;
    }
    }
    public class JavaDemo{
    public static void main(String arg[]){
    Color c=Color.getInstance("green");
    System.out.println(c);
    }
    }

- 枚举

  • 主要作用:用于定义有限个数对象的一种结构(多例设计),枚举就属于多例设计
1
2
3
4
enum Color{
Green,Red,Blue;
}
main:System.out.println(Color.Green);
  • 枚举的本质:相当于一个类,但是这个类默认会继承Enum类

  • 方法:

    No. 方法名称 类型 参数类型
    01 protected Enum(String name,int ordinal) 构造 传入名字和序号
    02 public final String name() 普通 获得对象名字
    03 public final int ordinal() 普通 获得对象序号

    总结:在枚举中,每一个对象的序号都是根据枚举对象的顺序来决定的

    问:enum与Enum的区别?

    答:1.enum:是从JDK1.5之后提供的一个关键字,用于定义枚举类;

    ​ 2.Enum:是一个抽象类,所以使用enum定义的类就默认继承此类

  • 定义枚举结构:枚举虽然也是多例的设计模式,但是不同点在于,枚举不能定义私有的构造方法,而多例可以

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    enum Color{//枚举类
    RED("红色"),GREEN("绿色"),BLUE("蓝色");//枚举对象要写在首行
    private String title;//定义属性
    private Color(String title){
    this.title=title;
    }
    public String toString(){
    return this.title;
    }
    }
    public class JavaDemo{
    public static void mian(String args[]){
    for(Color c:Color.values()){
    System.out.println(c.ordinal()+"-"+c.name()+"-"+c)
    }
    }
    }

    总结:

    1. 枚举对象要写在首行
    2. 枚举类也可以调用接口
    3. 枚举类可以直接定义抽象方法。并且要求每个对象都要独立覆写此方法

- 内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Outer{//外部类
private String msg="www.mldn.cn";//私有成员属性
public void fun(){//普通方法
Inner in= new Inner(this);
in.print();
}
public String getMsg(){
return this.msg;
}
class Inner{//在Outer类内部定义了Inner类·
private Outer out;
public Inner(Outer out){
this.out=out;
}
public void print(){
System.out.println(this.out.getMsg());
}
}
}

public class inner_class {
public static void main(String[] args) {
Outer out=new Outer();
out.fun();
}
}

内部类存在的意义:可以通过内部类访问外部类的私有属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package inner_class;
//接口内部类
interface IChannel{//定义接口
public void send();//发送消息
class ChannelImpl implements IChannel{
public void send(){
System.out.println("www.mldn.cn");
}
}
public static IChannel getInstance(){
return new ChannelImpl();
}
}
public class inner_interface {
public static void main(String[] args) {
IChannel channel=IChannel.getInstance();
channel.send();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package inner_class;

class Outer1{
private static final String MSG="www.mldn.cn";
static class Inner{//static定义内部类
public void print(){
System.out.println(Outer1.MSG);
}
}
}
public class static_innercalss {
public static void main(String[] args) {
Outer1.Inner in=new Outer1.Inner();
in.print();
}

static 定义的不管是类还是方法,只能访问static成员,所以static定义的内部类只能够访问外部类的static属性或方法,这个时候Inner类是一个独立的类,如果此时要想实例化Inner类对象。需要根据外部类.内部类实例化对象即可

static定义内部类的形式并不常用,static定义内部接口的形式最为常用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package inner_class;

interface IMessageWarp{//消息包装
static interface IMessage{//定义静态的内部接口
public String getContent();
}
static interface IChannel{
public boolean connect();//消息发送通道
}
public static void send(IMessage msg,IChannel channel){
if(channel.connect()){
System.out.println(msg.getContent());
}else{
System.out.println("消息通道无法建立,消息发送失败");
}
}
}

class DefaultMessage implements IMessageWarp.IMessage {
public String getContent(){
return "www.mldn.cn";
}
}
class NetChannel implements IMessageWarp.IChannel{
public boolean connect(){
return true;
}
}
public class static_interface {
public static void main(String[] args) {
IMessageWarp.send(new DefaultMessage(),new NetChannel());
}
}

之所以用static定义内部接口,主要是因为这些操作是属于一组相关的定义,有了外部接口之后可以更加明确得描述这些接口的主要目的和功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//方法中定义内部类
package inner_class;

class Outer2{//外部类
private String msg="www.mldn.cn";//私有成员属性
public void fun(){//普通方法
Inner in= new Inner(this);
in.print();
}
public String getMsg(){
return this.msg;
}
class Inner{//在Outer类内部定义了Inner类·
private Outer2 out;
public Inner(Outer2 out){
this.out=out;
}
public void print(){
System.out.println(this.out.getMsg());
}
}
}

public class inner_class {
public static void main(String[] args) {
Outer2 out=new Outer2();
out.fun();
}
}
//在方法内部提供有Inner内部类的定义,并且内部类可以直接访问外部类中的私有属性也可以访问方法中的参数

内部类可以定义在任意结构中,这就包括:类中,方法中,代码块中,但是从实际开发来讲在方法中定义内部类的形式较多;

- 函数式编程

- Lambda表达式

Lambda表达式格式:

  • 方法没有参数:()->{};
  • 方法有参数:(参数,参数)->{};
  • 只有一条语句返回:(参数,参数)->语句;

Lambda表达式注意点:主要用来定义行内执行方法类型接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package inner_class;

interface Imessage{
public void send(String str);
}
public class lamada {
public static void main(String[] args) {
Imessage msg=(str)->{
System.out.println("发送消息:"+str);
};
msg.send("www.mldn.cn");
}
}

- 方法引用

引用最大的特点是可以进行内存的指向处理,但是在传统开发之中所使用的只是对象的引用操作,而从JDK1.8之后提供了方法的引用,即:不同的方法名称可以描述同一个方法。

  • 引用静态方法:类名称::static方法名称;

  • 引用某个实例对象的方法:实例化对象::普通方法;

  • 引用特定类型的方法:特定类::普通方法;

  • 引用构造方法:类名称::new;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package inner_class;
    @FunctionalInterface//函数式接口
    //P描述的是参数,R描述的是返回值
    interface IFunction<P,R>{
    public R change(P p);
    }
    public class lamada {
    public static void main(String[] args) {
    IFunction<Integer,String> fun=String::valueOf;
    String str=fun.change(100);
    System.out.println(str.length());
    }
    }
    //利用方法引用这一概念可以为一个方法定义多个名字,但是要求必须是函数式接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @FunctionalInterface//函数式接口
    //P描述的是参数
    interface IFunction<P>{
    public int compare(P p1,P p2);
    }
    public class lamada {
    public static void main(String[] args) {
    IFunction<String> fun=String::compareTo;
    System.out.println(fun.compare("A","b"));
    }
    }

- 内建式函数接口

存在于java.util.function包,可以不用创建大量的@FunctionalInterface//函数式接口

  • 功能性性函数式接口:String类:以startsWith为例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    package inner_class;

    import java.util.function.*;
    public class lamada {
    public static void main(String[] args) {
    Function<String,Boolean> fun="**Hell0"::startsWith;
    System.out.println(fun.apply("*"));
    }
    }
  • 消费型函数式接口

    1
    2
    3
    4
    5
    6
    7
    import java.util.function.*;
    public class lamada {
    public static void main(String[] args) {
    Consumer<String> con= System.out::println;
    con.accept("Hello World");
    }
    }
  • 供给型函数接口:以String类中toLowerCase()为例,这个方法没有参数,但有返回值

    1
    2
    3
    4
    5
    6
    7
    8
    import java.util.Locale;
    import java.util.function.*;
    public class lamada {
    public static void main(String[] args) {
    Supplier<String> sup="HELLOW,WORLD"::toLowerCase;
    System.out.println(sup.get());
    }
    }
  • 断言型函数接口:以String类中的equalsIgnoreCase()方法为例

    1
    2
    3
    4
    5
    6
    7
    import java.util.function.*;
    public class lamada {
    public static void main(String[] args) {
    Predicate<String> pre="mldn"::equalsIgnoreCase;
    System.out.println(pre.test("Mldn"));
    }
    }

- 链表的定义与使用

![image-20210513205736962](../../../我的坚果云/基于Java/Java学习路线/阶段1 Java语言基础/img/image-20210513205601920.png)

链表结构:

image-20210513211255569

数据保存:public void add(E e)

注意点:进行链表操作的过程中为了避免转型的异常应该使用泛型,同时也应该设计一个链表的执行接口,并且具体实现该接口的时候还应该通过Node类做出节点的关系描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
interface Ilink<E>{//设置泛型避免安全隐患
public void add(E e);//增加数据
public int size();//获取数据个数
public boolean isEmpty();//判断是否为空
public Object[] toArray();//将集合元素以数组的形式返回
public E get(int index);//根据索引获得数据
public void set(int index,E data);//修改索引数据
public boolean contains(E data);//判断数据是否存在
public void remove(E data);//数据删除
public void clean();//链表清空
}
class LinkImpl<E> implements Ilink<E> {//链表处理类
//------------------以下为Node类----------------------
private class Node{//保存节点的数据关系
private E data;//保存的数据
private Node next;//保存下一个引用
public Node(E data){//有数据的时候才有意义
this.data=data;
}
//第一次调用:this=LinkImpl.root;
//第二次调用:this=LinkImpl.root.next;
//第三次调用:this=LinkImpl.root.next.next;
public void addNode(Node newNode){//保存新的Node数据
if (this.next==null){//当前节点的下一个节点
this.next=newNode;//保存当前节点
}else{
this.next.addNode(newNode);
}
}

//第一次调用:this=LinkImpl.root
//第二次调用:this=LinkImpl.root.next
//第三次调用:this=LinkImp.root.next.next;
public void toArrayNode(){
LinkImpl.this.returnData[LinkImpl.this.foot++]=this.data;
if(this.next!=null){//还有下一个数据
this.next.toArrayNode();
}
}
public E getNode(int index){
if(LinkImpl.this.foot++==index){//索引相同
return this.data;//返回当前数据
}else{
return this.next.getNode(index);
}
}
public void setNode(int index,E data){
if (LinkImpl.this.foot++==index){//索引相同
this.data= data;//修改数据
}else{
this.next.setNode(index,data);
}
}
public boolean contaisNode(E data){
if(data.equals(this.data)){//对象比较
return true;
}else{
if(this.next==null){//没有后续节点
return false;//找不到
}else{
return this.next.contaisNode(data);//向后继续判断
}
}
}
public void removeNode(Node previous,E data){
if (this.data.equals(data)){
previous.next=this.next;//空出当前节点
}else{
if(this.next!=null){
this.next.removeNode(this,data);
}
}
}

}
//------------------------以上为Node类--------------------
//---------以下为Link类中定义的成员---------
private Node root;//保存根元素
private int count=0;//保存数据个数
private int foot=0;//描述操作数组的角标
private Object[] returnData;//返回数据的保存
//---------以下为Link定义的方法---------
@Override
public void add(E e) {
if(e==null){//保存的数据为null
return;//方法调用直接结束
}
//数据本身不具有关联性,只有Node类有,那么想要关联处理就必须将数据包装在Node类之中
Node newNode=new Node(e);//创建一个新节点
if(this.root==null){//现在没有根节点
this.root=newNode;//第一个节点作为根节点
}else{
this.root.addNode(newNode);//将新节点保存在合适的位置
}
this.count++;
}
public int size(){//返回链表的元素个数
return this.count;
}
@Override
public boolean isEmpty(){
//return this.root==null;
return this.count==0;
}
@Override
public Object[] toArray() {
if(this.isEmpty()){//空集合
return null;
}
this.foot=0;//角标清零
// System.out.println(this.count);
this.returnData=new Object[this.count];//根据已有的长度开辟数组
this.root.toArrayNode();//利用Node类进行递归数据获取
return this.returnData;
}

@Override
public E get(int index) {
if (index>this.count){//索引应该在指定的范围之内
return null;
}//索引数据的获取应该由Node
this.foot=0;//重置索引为0
return this.root.getNode(index);
}

@Override
public void set(int index, E data) {
if (index>=this.count){//索引应该在指定的范围之内
return;//方法结束
}//索引数据的获取应该由Node类完成
this.foot=0;//重置索引的下标
this.root.setNode(index,data);//修改数据

}

@Override
public boolean contains(E data) {
if(data==null){
return false;//没有数据
}
return this.root.contaisNode(data);//交给Node类判断
}
@Override
public void remove(E data) {
if (this.contains(data)){//判断是否存在
if(this.root.data.equals(data)){//根节点为要删除节点
this.root=this.root.next;//根的下一个节点
}else{//交由Node类负责删除
this.root.next.removeNode(this.root,data);
}
this.count--;
}
}

@Override
public void clean() {
this.root=null;
this.count=0;
}
}




public class Link {
public static void main(String[] args) {
Ilink<String> all=new LinkImpl<String>();
System.out.println("【增加之前】数据个数"+all.size()+"是否为空集合"+all.isEmpty());
all.add("Hello");
all.add("张栩");
all.add("haha");
all.set(1,"世界");
System.out.println("【增加之后】数据个数"+all.size()+"是否为空集合"+all.isEmpty());
Object[] result=all.toArray();
for (Object obj:result){
System.out.println(obj);
}
System.out.println("------------数据获取的分割线-----------");
System.out.println(all.get(0));
System.out.println(all.get(1));
System.out.println(all.get(2));
System.out.println("------------ 数据判断的分割线----------");
System.out.println(all.contains("h"));
System.out.println(all.contains("世界"));
System.out.println("------------ 数据移除 --------------");
all.remove("世界");
Object[] result1=all.toArray();
for (Object obj:result1){
System.out.println(obj);
}
}
}

数组与链表的区别:

  • 数组的获取一个时间复杂度为1,而链表获取数据的时间复杂度为n;

![image-20210515155418544](../../../我的坚果云/基于Java/Java学习路线/阶段1 Java语言基础/img/image-20210515155418544.png)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package link_table;
//宠物商店 依赖于上部链表
interface Pet {//宠物标准
public String getColor();//获取颜色
public String getName();//获取名字
}

class Petshop{//宠物商店
private Ilink<Pet> allPets=new LinkImpl<Pet>();//保存多个宠物对象
public void add(Pet pet){//追加宠物,商品上架
this.allPets.add(pet);//集合中保存对象
}
public void delete(Pet pet){
this.allPets.remove(pet);
}
public Ilink<Pet> search(String keyword){
Ilink<Pet> searchResult=new LinkImpl<Pet>();//保存查询结果
Object result[]=this.allPets.toArray();//获取全部数据
if(result!=null){
for (Object obj:result){
Pet pet=(Pet) obj;
if(pet.getName().contains(keyword)||pet.getColor().contains(keyword)){
searchResult.add(pet);//保存查询结果
}
}
}
return searchResult;
}
}

class Cat implements Pet{//实现宠物标准
private String name;
private String color;
public Cat(String name,String color){
this.name=name;
this.color=color;
}

@Override
public String getColor() {
return this.color;
}

@Override
public String getName() {
return this.name;
}

public boolean equals(Object obj){
if (obj==null){
return false;
}
if (!(obj instanceof Cat)){
return false;
}
if (this==obj){
return true;
}
Cat cat=(Cat) obj;
return this.name.equals(cat.name)&&this.color.equals(cat.color);
}
public String toString(){
return "【宠物猫】:名字:"+this.name+",颜色:"+this.color;
}
}
public class Shop_pet {
public static void main(String[] args) {
Petshop shop=new Petshop();
shop.add(new Cat("黄斑狗","绿色"));
shop.add(new Cat("小强猫","蓝色"));
shop.add(new Cat("黄狗","黄色"));
Object result[]=shop.search("色").toArray();
for (Object obj:result){
System.out.println(obj);
}

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package link_table;
//超市购物车
interface IGoods{//商品标准
public String getname();
public double getprice();
}
interface IShopcar{//购物车标准
public void add(IGoods goods);//添加商品信息
public void delete(IGoods goods);//删除商品
public Object[] getAll();//获得购物车全部商品信息
}
class ShopCarImp implements IShopcar{//定义购物车的实现类
private Ilink<IGoods> allGoodses=new LinkImpl<IGoods>();
@Override
public void add(IGoods goods) {
this.allGoodses.add(goods);
}

@Override
public void delete(IGoods goods) {
this.allGoodses.remove(goods);
}

@Override
public Object[] getAll() {
return this.allGoodses.toArray();
}//购物车

}

class Cashier{//收银台
private IShopcar shopcar;
public Cashier(IShopcar shopcar){
this.shopcar=shopcar;
}
public double allPrice() {//计算总价
double all=0.0;
Object result[]=this.shopcar.getAll();
for (Object obj:result){
IGoods goods=(IGoods)obj;
all+=goods.getprice();
}
return all;
}
public int allCount(){//商品数量
return this.shopcar.getAll().length;
}
}

class Book implements IGoods{//书本类
private String name;
private double price;
public Book(String name,double price){
this.name=name;
this.price=price;
}
@Override
public String getname() {
return this.name;
}

@Override
public double getprice() {
return this.price;
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (!(obj instanceof Book)){
return false;
}
Book book=(Book)obj;
return this.name.equals(book.name)&&this.price==book.price;
}
public String toString(){
return "【图书信息】名称:"+this.name+"价格为:"+this.price;
}
}



public class Shop {
public static void main(String[] args) {
IShopcar car=new ShopCarImp();
car.add(new Book("西游记",20));
car.add(new Book("红楼梦",30));
car.add(new Book("Java成神之路",20));
car.add(new Book("三国演义",40));
Cashier cas=new Cashier(car);
System.out.println("总价格:"+cas.allPrice()+"总数量:"+cas.allCount());
}
}

- 面向对象设计的特征

  • 封装行,继承,多态

  • 面向对象程序开发的步骤

    > OOA:面向对象分析

    > OOD:面向对象设计

    > OOP:面向对象编程

- IO流

- 字节流

- fileinputstream( )
- fileoutputstream()