java00_知识点整理

javaOO知识点汇总

-->OO:Object Oriented-->面向对象.

1.类,对象,包

(1)对象

对象因关注而产生,万物皆对象.

1.结构化编程:

面向过程的结构化编程是将整个工程分布式的按照步骤从上到下依次执行。

2.面向对象编程:

面向对象就是在模拟生活中的各种场景.
面向对象:通过对象之间的属性和行为的相互关联来完成特定的功能.
建立对象模型,将问题域化为不同的对象去处理.
|-->找对象 ---->创建一个类来描述对象的行为和属性

3.面向对象和面向过程的区别:

面向过程是将整个业务流程分解成若干步骤,最后再按照先后顺序串联起来,程序围绕着问题的本身
来设计; 面向对象要先明确一个对象的行为和属性,程序围绕着问题域中的对象来设计.

(2)类

类是对象的抽象,对象是类的实例。

1.类的特征:

在面向对象的编程中,类是一个独立的程序单元,是具有相同属性和行为的一组对象的集合。
在程序中用类来模拟现实中的实体。 其规则有:类首字母大写(驼峰命名法);
文件名必须和public类对应的类名保持一致;一个文件可以定义多个类,但是只有一个public类
类可以看做是模板,产生的实例是对象.
方法:访问修饰符--返回类型--方法名称--参数列表--方法体

2.类的三要素:

1)类的标志--类的一个有别于其他类的必不可少的名字。
2)属性的说明:用来描述相同对象的静态特征,
3)类的方法--相同对象动态的特征(针对对象时就是行为,针对类时就是方法)

3.实例化对象

类是抽象出来的概念,对象才是真实存在的实体。 程序中通过类来实例化对象(new)

4.this

this表示当前类中对象的引用。
创建(new)的是哪个对象,this就表示这个对象的引用

(3)包

对文件的分类和管理-->文件夹

提供了一个组织类的机制,可以表示类的全路径,
包可以用来分辨类,包的命名方式采用公司的网址。com.xxx.包name,并且包名要小写.
包名(com.xxx.xxx)-->位于Java文件的首行,表示当前文件在某个文件夹下

系统包:java.功能.类名--> 命名时尽量不要使用系统使用过的名字

java.lang-基础类/java.util-工具类/java.io-输入输出类
要使用其他包下面的类,使用import来导入,或者:包名.类名(.*)
import不能导入本文件所在的类--会提示警告,默认就是导入本类

2.对象的行为

(1)栈,队列

栈是一端受限,一端允许操作的限线表--先进后出. 例:洗碗洗好放到篮子底下的最后才能拿出来
队列是限定性的限线表--先进先出. 例:排队买票,先排队先买票,后排队候买票。

(2)方法调用栈

定义多个方法,互相调用,先执行的方法后结束,后执行的方法先结束.
改变流程控制的方式:方法调用,选择语句,循环语句.

(3)重载

方法名相同,参数列表不同

当一个类有两个到多个同名但是有不同参数列表的方法时,就是方法的重载
参数列表:参数的类型,参数的个数,参数的前后位置
重载提高了方法的利用率:相同的行为,不同的表现形式

public class Fuction {
    public void show() {
        System.out.println("这是无参方法");
    }   
    public void show(int id) {
        System.out.println("这是有1个int参数的方法");
    }   
    public void show(String name) {
        System.out.println("这是有1个String参数的方法");
    }   
    public void show(int id, String name) {
        System.out.println("这是有2个参数的方法");
    }
    public void show(String name, int id) {
        System.out.println("这是有2个参数的方法,与上个方法参数位置不同");
    }
}  

(4)构造器

与类名一致并且只在实例化时被执行一次的特殊方法

构造器的目的是初始化类的实例,使其成为一个有效的状态. 构造器也是重载的一种表现,创建对象的时候,虚拟机会根据参数列表来决定调用哪个构造方法.
在实例化对象时,若类中没有无参构造,则编译器会自动创建一个默认的无参构造;
若创建了一个有参构造那么编译器就不会再加上默认的无参构造.

public class Fuction {
    public Fuction() {
        System.out.println("这是无参构造");
    }   
    public Fuction(int id, String name, int age) {
        System.out.println("这是有参构造");
    }   
    public int show(int id) {
        System.out.println("这是普通方法");
        return id;
    }
}  

1-构造函数的作用:

1)创建对象:创建对象的时候必须要有构造,可以初始化一些内容,由虚拟机来调用;
2)对象的初始化:构造函数可以对对象进行初始化,每一个类必须要有构造.

2-构造器和普通方法的区别

1)格式不同:构造方法不存在返回值,方法名必须和类型一致;普通方法可以有返回值,名称可以和类名不同,只要符合规范就行;
2)调用的时间不同:构造方法总是在类创建的时候运行;普通方法必须是对象调用时才执行;
3)执行次数不同:一个对象创建后构造方法只在new的时候执行一次;普通函数由对象来调用,调用一次就执行一次

3-构造方法使用的场景:

在分析具体事物的时候,发现事物一出现就具备了某些特征,就可以将其定义在构造中.

3.继承

面向对象的特征:封装,继承,多态,抽象.

(1)继承的概念:

在java中继承表示的是类与类之间的关系,是is-a的关系. 除继承外类与类之间还有组合关系has-a. has-a是类之间相互依赖的表现;is-a是继承中子类和父类的关系,它们都可以达到代码的复用. 类是单继承的,一个类只有一个父类. 通过extends关键字实现类的继承.父类(基类)-->子类(派生类) 通过扩展已有的父类/基类,创建一个新的子类/衍生类/派生类. 就可以拥有父类的所有的属性和方法,并且子类还可以扩展父类的属性和方法 public class Doctor extends Peopel { //Doctor是子类,它继承了Peopel类 }

(2)方法的重写:

当子类继承父类之后,当子类中的方法和父类方法的方法名一样 参数一样 返回类型一样,就可以称为子类重写了父类的方法.重写之后会优先调用子类的方法. 重写的规则:1.子类方法必须与父类方法的返回值类型 方法名和形式参数一致;2.子类的访问修饰符不可大于父类 3.子类不可抛出比父类更多的异常. 重写与重载的区别:重写是子类方法与父类方法之间关系的体现;重载是一个类当中多个方法之间参数不同的体现. @Override是伪代码,表示当前方法是重写方法:
a.可以将@Override看成是注解; b.增强了代码的可读性,该标签可以表示它是一个重写的方法.

public class Doctor extends Peopel {
     @Override public int attack() {
         int docAtta = super.attack(); return docAtta; 
    }

     @Override public int defense(int foeAttack) {
        int docDefen = super.defense(foeAttack); return docDefen; 
    }

    @Override public void lvUp() { 
        super.lvUp(); 
    } 
}  

(3)Object类

Object类是所有类根类,一个类如果没有显式的继承Object,虚拟机都会自动加上extends Object. equals()方法是Objiect类的方法,是用来判断两个对象的引用是否相等. 如果在子类想要判断两个对象的内容是否相等,就需要在子类重写equals方法.子类调用的时候就优先调用重写后的方法; toString: 一个字符串想要和另外一个类型进行连接,toString方法可以将其他类型转换为字符串再进行连接. 如果输入的是对象,默认调用toString并打印:内存地址+hashcode码. 对象-->getclass():类对象;new实例化的对象:类的对象. 类的对象关注的是数据;类对象关注的是属性.

重写equals方法目的是判断对象的行为和属性是否相同
创建子类对象首先会去调用父类的构造,然后再执行子类的构造
-->首先产生父类对象,再产生子类对象,所以子类可以共享父类的属性和行为
重写和重载:两个方法分别在父类和子类中,并且方法名和参数列表都相同,就称为重写
重载是指在同一个类中的方法,他们的方法名相同并且参数列表不同,体现的是相同的引用不同的表现形式
父类对象属性初始化-->父类构造-->子类对象属性初始化-->子类构造

this

子类定义了和父类相同的属性则this.属性指代得是子类本身的属性,-->属性没有重写,它们属于不同的对象
若子类没有改属性则this.属性指代的是共享自父类的属性,

super.方法

表示调用父类的方法-->super表示指向父类对象的引用
在子类构造中可以动态控制调用哪个构造super()调用无参构造,传入参数后根据参数类型确定调用哪个构造
父类相当于模板,子类继承的只是模板中属性的引用和方法,不继承数据

final关键字:

final修饰类,表示当前类为终态类(最终类),不能被继承;final修饰方法,表示该方法不能被重写; final修饰变量,表示该变量的值不能被修改(常量).

4.封装

java设计理念之一:
各个模块之间尽量减少关联,相互独立。

(1)封装的概念:

将类中的信息隐藏在类的内部,不允许外部程序直接访问,而是通过类提供的一些方法进行访问和操作。 字面上理解就是包装的意思-->信息隐藏,利用抽象数据类型将数据和类操作捆绑在一起,使其成为一个不可分割的实体。 外部不需要知道对象里面的细节,但是外部用户可以通过类对外暴露的接口来访问对象 封装的优点:1.可以对变量设置只读和只写; 2.可以对其中的成员变量进行整体控制(控制对象的结构); 3.类的用户不需要知道类中是如何存储和操作数据的; 4.良好地封装可以减小耦合

(2)访问修饰符:

public:公开级别的访问,任何对象都可以访问,没有包的限制; protected:受保护访问级别,同一个包中的类可以访问 子类可以访问(不管子类是否同包); 默认修饰符:默认访问级别,同一个包中的类可以访问; private:私有访问级别,权限最低的访问级别,只有本来可操作,不对外公开。 如果父类设置的属性和方法是private,那子类是无法访问和重写的, public > protected > 默认 > private

(3)javabean:

1.概念:

bean中文释义为豆子,javabean是一种特殊的类,通常用来实现一些简单的功能,很容易被重用也很容易被插入到其他应用程序, 按照bean规则编写的类都可以被成为javabean。 bean的含义是可以重复使用的java组件,组件是一个可以进行自由内部管理的一个或几个类所组成,外部程序无需了解其内部信息和运行方式, 想要使用就只能通过暴露的接口-->内部信息隐藏、进行数据传递.

2.javabean的规范:

所有的javabean必须放在一个包中(bean包); javabean必须要生成publicclass 类,文件的名字必须和类名一致 所有的属性都必须进行封装(private),不能出现public属性 私有属性通过get方法获取,通过set方法进行设置 必须要有一个无参构造

3.javabean的结构:

属性:javabean的类成员变量,描述javabean对象的状态; 方法:构造方法,普通方法; 事件:可用来监控属性的修改

(4)static变量:

1.static静态的概念

在java里面沒有全局变量的概念,但是我們可以通過一個static关键字構造一個伪全局变量,static表示"全局"、"静态"。 如果用static来修饰了某一个变量,那这个变量就属于类变量(不再是对象的成员变量),通过对象的引用可以获取static变量。 JVM在加载类的时候会把变量分成两种类型,一个是成员变量一个是静态变量(全局),如果存在静态变量则在加载类的时候就会将其保存到方法区(共享), 而成员变量就必须要在创建对象的时候才会加载到内存。 静态变量(类变量)在内存中一旦改变就不可恢复,类所有的实例都可以共享静态变量,可以通过类访问也可通过对象的引用来访问

2.static方法:

可以通过static来修饰称为静态方法(类方法),main方法就是典型的静态方法, 静态方法里面不能直接使用成员变量,只能使用静态变量,可以调用其他静态方法但不能调用普通方法,只能通过对象调用普通方法; 而在普通方法中就即可使用静态变量也可使用非静态变量,即可调用静态方法也可调用非静态方法.

3.静态块:

初始化块--> { xxx },用来对对象的数据进行赋值,一旦发现有对象产生就会自动执行初始化块在赋值时将 =??? 的操作放入构造. 静态块 --> static{ xxx },静态块也是用于初始化数据,但只会在第一次产生对象的时候执行一次. 静态变量可以加载很多数据信息,或者操作文件.下次通过成员变量就只能引用静态变量.

5.多态和抽象:

动态多态和静态多态,相同的行为,不同的表现.

(1)多态概述:

对象的多种形态,多态在很多面向对象语言中都存在,生物学中的多态是指生物存在很多形态和阶段,而在OOP中指的是一个对象有多种形式的能力-->相同行为有不同的表现形式.
静态多态:通过重载机制实现,在编译时就确定会加载那个方法;
动态多态(引用多态):通过继承的父类引用可以指向不同子类对象的特性实现,需要在程序运行时才能确定要加载那个子类;
方法多态:父类引用指向的是哪个实例就调用该对象的方法,如果被指向的子类没有这个方法,就调用继承自父类的方法。
多态的优势: 通过父类的引用可以共享所有子类方法和属性;
向上转型和向下转型: 基本数据类型的自动提升属于向上转型,向下转型即使强转为更小的类;
父类引用指向子类对象是子类对象默认向上转型为父类对象的具现.
对象的向上转型:子类可以共享父类的属性和方法,还可以扩展出子类独有的属性和方法, 当这个子类的引用属于父类对象时,自动发生的将子类向上提升为父类.
向上转型会导致子类一些属性和行为的丢失,因为父类引用无法指向父类模板中不存在的子类特有扩展功能,所有无法调用这些属性和行为;
向下转型:改变引用(强转),父类引用指向子类对象时,若还想使用子类特有的属性就要将该引用强制转换为特定 的子类(强转之后就没有多态特征了),强转之后的引用仍然可以指向原先的子类对象.
instanceof:比较前后两个对象是否属于同一个对象类型.
java多态可能导致引用和实际对象的类型不一致,这时可通过instanceof运算符来鉴别当前对象的类型.
instanceof虽然可以匹配对象类型,但是不推荐使用(没有很好的利用面向对象的多态性),可以用重载替换 instanceof

(2)多态存在的条件:

1.必须有继承; 2.必须有方法的重写;3.父类的引用指向子类对象. 抽象: 如果多个对象有相同的属性和行为,我们可以提取出这些共同点让这些对象共享. -->人类通过分析和综合在脑海中再现对象的本质和本质方法 抽象类:用关键字abstract修饰的一种特殊类,用来规定其子类必须实现的某些功能(抽象方法没有具体实现), 有多个相同特征的类抽象出一个抽象类,以该类为模板来规避子类设计的随意性. 一个类中若有抽象方法,那此类必须是抽象类,抽象类中可以有抽象方法也可由普通方法, 抽象类不能被实例化,只能作为其他类的父类。

(3)接口:

1.接口的概念:

接口是抽象方法和常量值的一個集合,是一直特殊的抽象類,只能有抽象方法不可有普通方法。 接口定义了某一些類所需要遵循的规范,但它不关注里面的数据和具体实现

2.接口的語法:

interface-->接口 class-->類 public [abstract] interface name[estends 接口1,接口2]{抽象方法, 常量 } []里面的内容可有可無。 接口还可以继承其他的接口並可实现多继承。

3.接口内部:

在接口里面定义的方法沒有abstract修飾,則编译器會自動加上.因为接口里面默认只能存在抽象方法; 在接口定义的常量會自动转换成 public static final *** ;接口里面只能存在公共的静态常量。 在接口里面的方法,若省略了访问修饰符,則會默认成为public。 接口的设计目的是用來被其他類实现的,因此類的访问权限也应该設置为public。

4.接口可以继承多個其他接口 ====>等价于一個類实现多個接口。

接口可以弥补java類不能多继承的缺陷,

6.异常处理

(1)异常概述:

异常是指程序在运行期间出现的错误.出现错误最重要的是查看代码行,关注错误的名字. Java在出现异常时默认将该错误打印到控制台.

(2)异常的分类:

Error:错误指的是用户或程序员无法控制的问题.系统内部出现的错误,程序设计时不需要在代码中进行处理;
Exception:所有异常的父类,其子类异常对应各种不同的异常情况,一般出现了异常都需要用户进行捕获处理,
检查异常,一般检查异常都是用户代码错误或者程序无法预见的错误。例如:打开不存在的文件 运行时异常--RunTimeException:在运行的过程中发生的,可以被避免的程序异常,可以忽略,提示设计人员该 段代码需要优化。程序无法预见的异常,如Math类除数为0 下标越界.

(3)异常的执行流程:

1.main方法在栈的最底部,method2在最顶部,如果method2抛出了异常,就会马上被弹出方法栈. 2.当前出现的问题会同时抛给方法调用者method1,然后在抛给main方法; 3.若main里面也没有处理该异常,Java虚拟机就会来处理这个异常,创建一个异常对象, 将信息通过调用tostring方法输出到控制台。

(4)异常的体系结构:

Throwable类是所以异常的基类;ClassNotFoundExceptiong/DataFormatException /IllegalAccessException/IOException/CloneNotSupportedException/NoSuchFielException/ 其直接子类是:Error类和Exception类
RunTimeException:ArrayStoreException/ClassCastException/ArithmeticException /NullPointerException/IllegalArgumentException Error/UnKnownError/OutOfMemoryError

(5)捕获异常:

try{}catch{} try里面放的是可能有异常的代码。一旦出现异常就可以自动进入catch块, 在里面打印输出该异常.若无异常就不执行catch块,不管catch块是否执行,后面的程序都会正常执行. try-catch-finally 块: finally为异常语句提供了一个统一的出口,可以对程序做一个统一的管理. 无论是否异常最后都要执行finally块。 可以通过finally块来进行资源的清理工作,关闭连接/关闭文件/删除某些临时文件. try或者catch里面有return语句也不影响finally模块的执行(这三个块是一个整体). 如果有多个catch块就要注意,catch块的顺序必须要从小到大(子类在前父类在后),同级别的异常就无要求

(6)声明并抛出异常:

throw:将异常进行抛出(动作);throws:声明将要抛出何种类型的异常(声明). 子类重写的方法,子类抛出的异常不能大于父类的异常, 但若是子类异常小于父类时,语法无错但无法全部接受来自父类的异常,所以无法调用父类方法。

(7)自定义异常:

某些异常在程序里面无法表达出来,就要自定义异常; 自定义规则:1.继承java.lang.Exception,声明自己是异常类; 2.在方法适当的位置生成自定义异常的实例,throw进行抛出; 3.用throws进行声明。

7.常用类:

(1)System类: err/out/in

1)代表了Java运行的平台(系统),通过system类可以进输入输出; 2)system类是final类,不能进行继承.其中的属性和方法都是静态的 3)常用的操作:程序的执行时间、数组的copy、获取一些系统信息 获取当前毫秒数-->currentTimeMillis();获取系统信息-->getProperties();

(2)Runtime类:

代表的是Java运行的环境,每个java程序都会有一个对应的Runtime对象,将程序和环境进行了一个连接. 程序不能自己创建Runtime对象,只能通过Runtime的静态方法getRuntime()获取实例. 获取虚拟机的最大内存-->maxMemory();

(3)字符串相关类(String/StringBuffer/StringBuilder):

String是一个不可变的字符串对象,一旦一个String被创建那么这个字符串中的内容就不可变, 直至该字符串被销毁. String类是一个final类不能被继承,以后我们操作字符串则会每次返回一个新的字符 串。拼接/排序/截取 String str = "abc"; 在编译期间就会在字符串常量池里面分配空间产生abc,并且被str指向; String str2 = "abc";-->str2会去常量池找abc,如果存在abc就直接通过str2 引用该abc。 String str3 = new String("abc"); 在运行时才会执行,在堆空间创建一个字符串对象,里面内容为abc, str3引用执行堆空间字符串,则每次都会产生一个新的对象。

(4)字符串中的方法:

获取下标为n的字符-->charAt(n);比较两个字符串-->compareTo(""); 将str2拼接到str-->str.concat(str2);(复制的方式,效率比+高) CharSequece(字符序列)-->contains(); endsWith(); 获取hash码-->hashcode(); equels在比较两个字符串的时候,实际上是比较hashcode编码, 如果两个字符串一样那么它们hashcode一定相等,若两个hashcode码一样则字符串不一定相等 忽略大小写-->equelsIgnoreCase(); 获取字符串的字节数据-->getBytes(); 获取字符串长度-->length(); 拆分字符串用,分割-->split(","); 将字符串转换成字符数组-->toCharArray(); 将值用字符串输出-->String.valueOf(xxx); 忽略首尾的空格-->trim();

(5)StringBuffer:

String和StringBuffer都是用来表示字符串,内部实现方式有差别,导致它们使用的范围不同, 对于StringBuffer,每次对字符串进行操作都是在原来的基础上继续增删改,不会产生新的字符串, 因此StringBuffer处理字符串的效率比String高. 定义一个字符串,若用StringBuffer的方式,就必须通过构造的方式进行初始化, StringBuffer s = new StringBuffer("sdfsdav"); s.append("asdfg").append("12345"); 字符串拼接效率: StringBuffer > concat > String ; 只定义一个字符串常量就使用String,若要对字符串进行大量的操作就使用StringBuffer;

(6)StringBuild

也是一个可变的字符串对象,与StringBuffer相比,线程不安全,适合单线程的程序使用, 所以其效率比StringBuffer高.

区别:
              类型
String       字符常量    不可变  线程安全   产生新对象 
StringBuffer 字符常量     可变   线程安全  不会产生新对象
StringBuild  字符串常量   可变   线程不安全  不会产生新对象

(7)日期相关类:

产生一个data实例就可以获取到日期(默认的时间). Date和Calender 是java里面的两个日期处理类,Data无法达到国际化标准,jdk1.1之后基本上用Calender来 替换,Data里面很多方法都被废弃了. 创建需要的日期格式,需要格式化日期,java.text.DateFormat抽象类,不能实例化,但是他提供了很多预定义 的日期格式. SimpleDateFormat:根据用户自定义的格式来显示日期.-->针对Date类型的转换 除了将日期转换为指的格式外,还可将字符串转换为日期格式. Calendar不支持SimpleDateFormat,必须先将Calendar转化为Date才能用SimpleDateFormat设置格式.

(8)Math类:

随机数-->random 向下取整-->floor 向上取整-->ceil 四舍五入-->round pow 平方根-->sqrt() Random: Random类中实现的类都是伪随机.有规则的随机,在进行随机时,必须要提供一个种子数, 在种子数的基础上进行了一定的变化. 相同种子数产生的随机数是一样的. 通过时间产生的种子每次随机数都不一样.

(9)常用包装类

将基础类型的变量装箱成包装类对象,将包装类对象拆箱成基础类型的变量
针对基本数据类型的变量
java中以前皆对象,为基本数据的变量提供了一个包装类,可以将基础类型的变量当做对象一样进行操作。
所有的包装类都是final类型,不能创建子类.包装类一旦创建就不能改变里面的数据

number:int-->Integer,byte-->Byte,short-->Short,long-->Long,float-->Float,double-->Double;             
object: boolean-->Boolean  char-->Charactor    


代码实例:
Integer it = new Integer("365");
int res = it.intValue();  

int i = 12;
Integer it2 = new Integer(i);  

Integer it3 = Integer.parseInt("456");  

装箱和拆箱只针对包装类和基本数据类型.

8.正则表达式

用来验证特定格式的一个字符串模板.
使用String的matches()方法进行比较

1.字符类:

[abc]---->匹配a/匹配b或者匹配c  
[^abc] ---->可以匹配任何字符,除了abc  
[a-zA-Z]---->可以匹配字母a-z,A-Z      //[A-Z][a-z] Bn  
[0-9] ---->匹配数字  

2.预定义格式类:

. ---->任何字符,我就是.字符本身。    \.    
\d ----> 数字;  \D ---->非数字  
\w ----> [a-zA-Z0-9_]小写字母 大写字母 数字 下划线  
\W---->非字符。  [^\w]  

3边界匹配:

^ ---->表示行的开头  
$ ---->表示行的结尾  

4.数量词:

? 例如:[0-9]? 数字出现一次或一次也没有,  
* 例如:[0-9]* 数字出现0次或多次  
+ 例如: \\w+  或者 [a-z0-9]+  出现一次或多次  
{n} 例如 [0-9]{6} 6位数字  
{n,} 例如 [0-9]{6,} 数字6位或以上  
{n,m} 例如 [0-9]{4,8} 数字至少4次,最多8次  

5.运算符:

xy ---->x后面必须是y  
x|y ---->要么是x 要么是y  
(x) ----> 将括号里面的内容x 单独看成一个组    

6.中文:

[\u4e00-\u9fa5] ----> 匹配中文汉字  

9.集合框架

数组弊端:定长,同类型数据
集合:对象,容器,存数据。元素类型可不同,集合长度可变,空间不固定。存储,检索,传输对象。

(1)集合:

生活中指很多事物凑在一起,数学里指具有相同属性事物的一个整体,
java中指用来存储数据,一某种组织结构并一特点的方式来进行访问,目的是提供一个可以用来处理对象的集合和框架。(一种工具,容器,存储任意数量的对象)

(2)集合的作用:

1.在类的内部,对数据进行组织,比如当前每个学生都可以选择学习科目, 2.简单而快速的搜索内容

(3)集合的结构

collection:collection接口是最基本的集合接口,他不提供直接的实现,collection代表第一种规则。
所包含的元素都必须遵循一条或多条规则(某些实现类可以重复数据,也有的不能重复;
按照指定顺序插入或散列插入;排序或不排序),在程序中不会直接使用collection接口,都是使用它的子接口.

(4)list

list接口为collection的直接子接口,list接口代表的是有序的集合,使用某种特定的插入顺序来维护元素的数据。
对集合中每个元素获取到的精确位置进行访问,也就是通过索引访问元素,允许数据重复。
设置对象到集合里面,默认是用object来接收.

1.ArrayList:

ArrayList是list的实现类,是一个动态数组,底层是封装的数组,允许插入null.
创建ArrayList对象的时候,不用指定大小,虚拟机会默认设置初始容量10,该容量会随着数据的增加而增长,
每次添加数据都会判断容量是否足够,若将要溢出时就进行动态扩容,允许数据重复.

2.LinkedList:

实现了list接口的类,方法和属性和ArrayList类似,是一个双向链表结构的集合(记录了前后元素的位置),
额外提供了很多方法,如 insert。 区别: 底层方式不同,linkedlist不能随机访问,所有操作都是按照双向链表的要求执行,
要在里面获取元素必须从第一个元素开始遍历,但是在进行增加和删除或修改的操作时就效率比较高.
双向链表:每个元素在内存里面都是独立的,每个空间都会保存上一个和下一个元素的位置.

3.vector:

与 ArrayList非常相似,Java1.0开发出来的vector,在1.2版本后java才提出了集合框架,为了向下兼容,就将vector加入到了集合框架,同时与现有框架保持一致(放在list接口下面).
特定:vector线程同步,线程安全x效率低;底层是数组。

(5)泛型:

对集合中的元素类型进行约束,规定数据格式.
操作list会出现无论什么数据类型都可以加入到集合里面,这时当需要进行对象强转的时候就会出现异常.
如果王其中加入基本数据类型会进行自动装箱,取出时则进行自动拆箱。
概念:允许在定义类、接口时指定形参类型,而在list里面声明泛型也是对集合做数据类型的规范。
要求必须要传递那个类型的数据,否则就报错。
< ?>-->泛型的占位符,在定义时不确定数据类型,在运行产生实例时再来确定泛型的数据类型(多态).

(6)Set集合

set继承了collection,实现了collection的所有方法
特定:a.不能包含重复元素,当加入一个元素的时候,要判断元素的内容是否重复,
如果要往set集合加入对象就必须重写equals,才能判断当前对象是否重复; b.可能有顺序也可能没有顺序(无序); c.set是无序的,所以set集合不能用索引进行访问。

1.HashSet:

hashset是基于hash算法的set接口实现, 元素允许为空.
hashset无法通过索引访问,只能通过foreach或者迭代器进行循环.
往set集合中加入对象,要判断对象是否是同一个,需要判断对象的所有属性是否相等.
java中判断两个对象是否相等:
a.判断hashcode码是否相同(确定元素的位置--桶算法);如果hashcode码不相等那这两个对象就不能认为是相等; b.如果hashcode相等,接下来就比较equal方法(比较对象中的元素),如果不相等则对象不相等.

2.TreeSet

基于TreeMap实现,底层是二叉树.生成总是一个处于排序的set集合,
它可以让set里面的元素按照一定规则进行默认排序,也可以自定义顺序(排序:Comparator接口). 与HashSet比较:速度慢,排序。集合要排序就要将所有的元素进行两两比较,根据返回值进行排序.

(7)集合中两个比较器

两个接口comparable和comparator:
comparable可以看成是一个内比较器,两个对象中的元素可以进行相互比较,依赖于comparaTo进行自然比较,比较者大于被比较者返回值为正整数,等于则返回0小于则返回负整数;
comparator可以看成一个外比较器,适用于两个对象要进行相互比较但却不进行内部特定元素的比较,使用方法compara(object1,object2)进行比较,object1大于object2返回正整数,等于则返回0小于则返回负整数.

(8)迭代器:

Itrtator接口,Iterable接口,用于遍历集合中的数据(循环输出集合中的数据).
Itrtator对象,通过该对象可以操作集合中的每个元素.

(9)Map接口

每个条目单独包含两部分-->key value,键值key不可重复.
1.map和set、list的区别:
由键值对进行内容的组织,提供了key-value的印射
2.没有基础collection接口;
3.key-value是一一对应关系,key不可重复value可重;
4.map的实现类有: hashmap,treemap,hashtable 5.key是单独储存的,如果将所有key放在一起就是一个set集合(无序不可重)

1.hashmap

以hash表的结构来实现,通过hash算法进行位置寻找,查询快速,key不可重复value可以重复,允许空键空值;

2.TreeMap

TreeMap是基于红黑树算法来的,键值是放在set集合中的并对其进行了自然排序。TreeMap包含了treeSet

hashtable

hashmap和hashtable都是map的子类,hashtable先出来hashmap后出来,hashmap允许null键null值线程不安全,hashtable不允许空值线程安全效率较高.

10.IO流

数据从外部进入内存(input)和从内存取出(output)的过程,就是数据的输入输出(I/O).

(1)流的概念

流类似于在文件和程序之间的一个虚拟管道,数据可以按照特定方向流入或流出.
流就是一个管道里面有数据(二进制),这个管道连接了程序和文件.
java中当需要读取数据的时候,就会开启一个数据源设备的流(通过代码控制),这个数据源可以是文件、内存或网络路径;同样的当写入数据的时候,就会开启一个通往目的地的流(用代码创建一个虚拟管道)。
用流来抽象IO的原因:流的两个特征-->1.流是流质可以流动 2.流具有方向不能随意更改.

(2)流的分类

java.io包里面包含了所有流的内容,可以看成是存放各类型流的仓库.

1.按照方向:

1.输入流:将数据读取到内存,只能读取不能写入.InputStream,Reader;
2.输出流:将数据从程序写出到目的地,只能写入不能读取.OutputStream,Writer.

2.按照类型:

1.字节流:以byte为最小单位进行传输(8位),字节流都必须继承InputStream或OutputStream抽象类
2.字符流:以char为最小单位进行传输(16位),字符流必须继承Writer或Reader抽象类。

3.按照功能:

1.节点流:对特定数据源进行读写操作,可以直接操作数据底层(如内存、硬盘、二进制);
2.处理流:不直接连接设备而是连接在其他流上面的特殊流,通过对数据的处理为程序提供强大的功能(高级流).

(3)操作流的步骤:

1.建立流

根据不同的数据类型选择不同的流(创建管道);

2.操作流

将数据读取到内存或将内存中的数据写入到数据源;

3.关闭流

操作结束后需要关闭输入输出流.

(4)File类

java.io.File类主要用来管理磁盘文件或者文件目录的基本功能,可以获取到文件的信息,文件夹的一些操作。不能访问或者操作文件的内容。

(5)输入输出流

1.缓冲流:

BufferedInputStream,BufferedOutputStream  

在操作磁盘数据的时候,不用一直去访问磁盘,先将数据放在缓冲区,当数据读取完之后再一次性将数据写到硬盘,一次性读取到内存。

2.数据输出流,数据输入流:

DateInputStream,DateOutputStream

输出内容的时候,不管哪种数据类型都可以直接调用输出方法进行输出,底层就是封装了getbytes()。

3.字符输入流

reader、writer抽象类
以字符为单位进行数据传输,所有在传输的过程可以一次获取一个中文
inputstreamreader将字节流转换为字符流 outputstreamwriter将字节流转换成字符进行输出

4.字符流和字节流的选择:

在操作内容上,字节流擅长于处理二进制文件或者大型文件;
字符流擅长于处理文本文件(普通文档,中文),字节流操作中文后可能就无法读取到完整的中文.

(6)对象流

对象的序列化和反序列化.
序列化:将对象转化为byte序列进行传输,

public static void objChange(Student s){
    String objPath = "obj\\student.dat";        
    OutputStream out = null;
    ObjectOutputStream objout = null;
    try {
        out = new FileOutputStream(objPath);
        objout = new ObjectOutputStream(out);   
        //writeObject将对象进行序列化的方法
        objout.writeObject(s);
    }    
    。。。。。。。。。。。。 
} 

反序列化:将byte序列转化为对象以获取里面的内容.

public static void getObj(File f) throws Exception{
    //创建一个读取流和一个对象读取流
    FileInputStream in = new FileInputStream(f);
    ObjectInputStream objin = new ObjectInputStream(in);  
    //readObject将文件进行反序列化的方法,获取到存入其中的对象 
    Object obj = objin.readObject();
    Student stu = (Student)obj; 
    。。。。。。。。。。。。。       
}  

序列化流:ObjectOutputStream、ObjectInputStream、
-->writeObject(obj)方法可将传入的对象转化成二进制流(),对象必须实现Serializable接口,transient修饰符可以保护可序列化类中的属性不被序列化;
-->writeObject(obj)方法可以读取文件中的数据,获取到被序列化后的对象.

11.java图形界面

(1)awt和swing-->抽象类

在Java中提供了两套组件用于编写用户界面,-->AWT SWING
awt jdk提供的抽象窗口包,用于编写用户界面,采用的方法是在某平台基于底层的一个实现,严重依赖于操作系统,运行的外观取决于操作系统.重量级框架
Swing在awt基础上开发的新GUI轻量级组件,有纯java编写,不依赖于底层的操作系统,具有很高的可移植性.

JFrame类

容器和组件 用户界面必须有重量级的容器,swing的轻量级是指容器中的组件 lang.Object -->awt.Component -->awt.Container -->awt.Window -->awt.Frame -->swing.JFrame

(2)awt和swing的架构

Component:属于容器,所有可以显示出来的可见元素都可以称为Component
Container:归属于Component的一种特殊图形,但Container本身也是一个容器,可以容纳其他元素.
Container下面的子类 -->window --pannel
window是可以独立显示出来的,包含各种各样窗口的,一个独立的窗口.
Frame:就是我们平时看到的窗口
JFrame: 属于swing包的轻量级,其他的和Frame基本一致
Dialog:弹框,页面上的提示框、输入框、确认框等. pannel一个比较小的容器,可以容纳其他的布局元素,不能独立显示出来,必须要依赖于window.多用于小程序 -->Applet面板,用于分隔容器的空间,以更好的定位.
Jcomponet:Component的子类,属于swing包.里面装的是swing的容器和组件.

(3)容器和组件

容器和组件是组成GUI界面可见或不可见的内容,所有的容器也都是一种组件,二者的区别在于他们的用途.组件指可以独立的可视化控件--按钮、文本框、密码框;容器是被设计出来容纳其他容器或组件的模块.组件要显示出来就必须要放在容器中.

(4)布局管理

1.空布局(绝对布局):元素的位置可以更改,默认在左上角,setbounds设置坐标和大小;
2.流式布局:FlowLayout,元素从左到右一行满了就换一行;
3.BorderLayout边框布局,东南西北中五块;
4.GridLayout:表格布局,将空间划分为规则的矩形网络,每个区域的大小都相等;
5.CardLayout:卡片布局让几个组件共享一个显示空间,这些组件是堆叠起来的,通过卡片提供的一些操作可以动态切换组件;
6.GridBagLayout:网格布局

(5)内部类

1.什么是内部类:

定义在一个类的内部这样的类叫内部类,包含内部类的类叫外部类.

2.为什么要定义内部类

内部类可以把内部信息更好的封装到类的内部,内部类不允许同包中的其他类访问;
内部类可以访问它所在外部类的所有属性和方法(包括私有);
内部类实现的功能,外部类也能实现,但是内部类更方便;

3.内部类的分类:

--成员内部类、静态内部类、方法内部类、匿名内部类.

4.成员内部类

最常见的普通内部类,针对外部类的特殊补充.

public class InnerClass {
    private int num = 10;       
    public class inner{
        public int sum =100;
        public void show(){
            System.out.println(num);
            System.out.println(sum);
        }
    }       
    public static void main(String[] args) {
        InnerClass in = new InnerClass();
        System.out.println(in.num); //可以访问   

        //不可以直接访问内部类的属性
        //System.out.println(in.sum);

        //创建内部类实例要通过外部类
        inner in2 = in.new inner();
        in2.show();
    }
}  

特点:内部类可以直接访问外部类的属性和方法,外部类不能访问内部类的数据;
创建内部类对象必须通过 外部类引用.new 内部类
内部类和外部类是连个class文件,若内部类有与外部类相同的方法或属性,要访问外部类就必须通过 外部类.this.属性 (在内部类之中).

5.匿名内部类:

匿名内部类是指没有名字的内部类,它只能使用一次,通常用来简化代码;
使用匿名内部类就必须继承一个父类或者实现一个接口.

public abstract class InnerClass2 {
    public abstract void play();

    public static void main(String[] args) {
        InnerClass2 in = new InnerClass2(){
            @Override
            public void play() {
                System.out.println("这是匿名内部类");          
            }           
        };
        in.play();
    }
}   

(6)事件:

事件源对象 ----> 监听器对象
在事件源上注册监听器,--当某事件发生的时候(event-->封装了事件的信息,如鼠标坐标、事件类型等),该event对象就以参数的形式传入到监听器;
事件源:能够创建一个事件并触发该事件的组件,即是指能够操作的元素(事件类的根类:utile.EvevtObject).
监听器:能够处理事件源触发的某事件的对象就是监听器(用来监控某种行为的发生并执行相应的代码). 采用匿名内部类创建监听器表示当前按钮拥有的唯一监听器

12.java数据库--JDBC

Java DataBase Connectivity

(1)JDBC:

是Java提供的一套操作数据库的api,定义了一套用来访问数据库的标准类库.
位于java.sql/javax.sql,可以通过jdbc和各种数据库建立连接.

(2)原理:

1.java api 定义了一系列的规格,提供的是各种接口,需要数据库厂商来实现;
2.数据库厂商将实现接口的方法封装成了jar包,程序若需要访问相应的数据库,就必须下载对应的驱动;
3.jdbc也提供了一个驱动管理器,是一个实现类用于加载jdbc驱动的各个类,生成数据库连接,访问各个数据库都要用到驱动管理器.

(3)工作原理

应用程序-->Java Api -->驱动管理器-->JDBC驱动-->网络协议API-->数据库

(4)JDBC的驱动分类

1.JDBC-ODBC Bridge:移植性差,效率低
2.Native-API partly-Java driver:本地库Java驱动程序,维护较难
3.是的发送到
4.说得对发 在程序设计中如何选中驱动包:
若程序只会访问一个数据库就用第四种,若需要访问多个数据库就用第三种,若第四和第三种都不适合就用第二种,第一种基本上不会考虑,因为严重依赖于底层Windows系统移植性差效率低.

(5)JDBC--API

Driver接口:是所有jdbc驱动都要实现的一个接口,让数据库去实现,在程序中不会直接调用Driver而是要通过DriverManager调用实现; 驱动管理器:DriverManager,用于管理驱动; Connection:用于与特定数据库建立连接; Statement:用于执行静态的sql语句,通过调用connection提供的方法createStatement()创建该对象;
preparedStatement:预编译sql语句,也是通过connection对象来创建;
CallableStatement:用于执行数据库里面的存储过程; Resultset:用于接收sql查询的返回值,并处理返回值;

(6)jdbc连接数据库的步骤:

1.根据访问的数据库,加载不同的驱动类型;
2.连接到数据库,得到connection对象;
3.通过connection对象产生Statement(或preparedStatement),执行sql语句;
4.返回结果集,Resultset;
5.灰色资源,关闭连接.

(7)Statemen和PreparedStatement

Statement执行的是静态的sql,每次执行都要编译一次,可能发生sql注入;
PreparedStatement动态的sql,只编译一次以后就直接直接调用,不会再编译,可以防止sql注入.

(8)架构模式

1.MVC

属于一种架构理念,在大多数程序语言都有这个模式,并不是java特有的.
m(model):模型,用于封装数据传递数据,业务逻辑处理(文件操作);-->javabean
v(view)视图: 用于数据的显示和获取,用户可见的页面;-->JFrame/HTML
c(controller)控制器:用于获取数据并发送给视图,调用业务方法,但是它不处理业务.-->监听器

2.三层架构:

什么是三层架构,为什么要使用三层架构,区分三层架构和两层架构
什么是三层架构? 对系统进行架构的规范,将系统分为三部分,是设计模式的一种.
在程序中:-->表示层,显示数据接收数据; -->业务层,用于处理业务逻辑,完成某些既定功能;-->持久层,负责对数据进行一个持久化保存或者从中获取所需数据.
三层架构就是为了让系统分工明确,各司其职,来源于生活.

3.在Java中

表示层(UI层):用于接收和显示数据(交互界面);
业务层(service):连接表示层和持久层,处理业务逻辑(验证、算法、规则);
数据持久层(数据访问层):与数据库或文件交互,实现数据的增删改查,将数据库的数据提取出来传递给业务层或将业务层数据保存到数据库.
实体层(域模型层):串联三层做一个数据的传递,是单独的概念不属于任何一层(Entity).
1.实现了面向对象的封装思想;2.贯穿于三层在其中传递数据;3.对于初学者,数据库里面的一张表中的一行就对应一个实体,在程序中用实体来进行封装;4.简化了传递数据的方式(若是传递的变量太多就可以封装成实体bean).

4.开闭原则

开闭原则是面向对象复用设计的模块,指在程序设计中要对修改进行关闭,对扩展功能进行关闭,扩展功能的前提是不改变原来已有的代码。-->抽象化设计(抽象层接口)

5.依赖倒转原则

抽象不应该依赖于细节,即是有个面向接口进行编程而不是实现类.
抽象不应该依赖于细节(子类/实现类);3.细节应该依赖于抽象(父类/接口).
模块间的依赖是通过抽象发生的,-->接口的引用指向实现类(多态的应用),面向接口编程.
优点:采用依赖倒转可以减少类之间的耦合性(类之间的依赖关系),提高系统的可维护性,减少并行开发的风险.

6.三层架构的优缺点

1.结构清晰,耦合度低了;2.可维护性增加,可扩展性增加;
3.利于开发任务同步进行,适应需求变化;

缺点:降低了系统的性能,分层越多效率越低;增加了代码量和工作量.

13.多线程编程

(1)进程:

运行程序时首先会将代码放在方法区,但却并没有马上执行,但这个时候已经有一个进程在准备了,进程产生后代码还是没有运行,这就是一个进程.
进程是一个静态的概念,运行中的程序都是一个进程,拥有内存和cpu资源.
我们常说的进程开始运行,实际上是进程里面的主线程在开始运行了,系统调用main方法,就产生一个主线程,在计算机上运行的实际上是线程.

(2)线程

线程实际上就是进程里面的一段程序,一个进程可以有多段程序.
线程本身是不占任何资源的(共享进程的资源).
线程就相当于一个程序里面不同的执行路径.

(3)线程和进程的区别

每个进程都有自己独立的代码和进程空间,进程间进行切换时,内存开销比较大;
线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的线程栈和计数器.线程间的切换内存消耗小.
多进程:在操作系统中运行多个任务; 多线程:在同一个应用程序中有多个流程同时执行.

(4)处理器对线程任务的分配:

cpu运行的速度非常快,一秒钟可以执行几亿次.CPU将自己的时间分成了很多小的时间片段,某一个时间片在执行某线程,下一个时间片又在执行另一个线程,虽然系统要执行几十个线程,但是由于速度很快,感觉上就是同时在运行.
什么才是真正的多线程:计算机有多个CPU-->双核/四核.

(5)线程的创建

java.lang.Thread类,用来表示一个线程,创建也是用Thread来进行.
创建线程的两种方案: 1.写一个类继承Thread类,重写run方法;

class Thread1 extends Thread {
    @Override
    public void run() {  
        //重写run方法
    }
}  

2.写一个类实现Runnable接口,实现run方法.

public class RunTest {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Thread2(),"1号");
        Thread t2 = new Thread(new Thread2(),"2号");
        Thread t3 = new Thread(new Thread2(),"3号");         
        t1.start();
        t2.start();
        t3.start();
        System.out.println("main执行");
    }
}
class Thread2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"执行:"+i);
        }           
    }
}   

一旦执行程序,虚拟机会自动创建一个主线程(main),创建线程的实例就会产生一个线程,当前线程处于就绪状态,
在运行时处理器通过调用start方法使两个线程一起运行,由虚拟机通过CPU和线程的优先级等因素,来决定先执行哪个线程.
Thread类提供了一个静态方法currentThread().getName(),可以获取到当前运行线程的名字.

(6)线程优先级的概念

程序运行的顺序并不是按照创建线程的顺序来执行,而是通过优先级来控制的.
java线程的优先级:java提供了一个线程调度器来监控线程的运行,监控处于就绪状态的线程.
线程调度器会按照线程的优先级来决定调度哪一个线程来执行.
线程优先级是用数字来表示的(1-10),创建的线程缺省值默认就是5.
优先级的值越大表示优先级越高,main方法的优先级默认也是5.线程运行的顺序是有虚拟机来控制的,线程的优先级是相对的.
理论上优先级高的会首先占据运行的权利,但是实际上得到的结果并不是优先级高就完全占据执行的权利,线程运行的顺序和环境也是息息相关的.
具有高优先权的线程会分配更多的运行资源.

Thread3 t = new Thread3();
Thread4 t2 = new Thread4();
Thread5 t3 = new Thread5();     
t.start();
t.setPriority(t.MAX_PRIORITY);//设置优先级为最大值       
t2.start();
t2.setPriority(t2.MIN_PRIORITY);//设置优先级为最小值 
t3.start();
t3.setPriority(6);//设置优先级为6   

(7)线程的状态

1.新建状态:

当线程对象创建后就处于新建状态-->Thread t = new Thread();

2.就绪状态-Runnable:

当程序调用start方法,当前线程就处于就绪状态,但是还没有被执行

3.运行状态(Running):

当调度器到调用当前线程的时候,线程就进入运行状态,此时线程才处于运行,就绪状态是进入运行状态的唯一途径;

4.阻塞状态(Blocked):

处于运行中线程,可能会因为某些因素放弃对CPU的使用,停止运行,这个时候线程就处于阻塞状态,要回到就绪状态才能继续运行;

5.死亡状态(Dead):

线程执行完毕或者因为某些因素异常退出了,该线程就结束了生命周期,等待被回收.
sleep()让运行的线程处于阻塞状态,yield()暂停当前正在执行的线程对象,并执行其他线程(让运行的线程回到就绪状态).
join()让其他线程停止运行,等待该线程执行完毕,再运行其他线程.

(8)多线程的关系图

1.锁机制:

当两个或者两个以上的线程要同时访问共享数据的时候,必须确保某一个时间点只能有一个线程进行访问,这个过程就是同步-->锁机制.

3.同步块、同步方法:-->synchronized

处于同步方法或同步块里的程序,要进行等待,我就调用wait(),可以让线程处于等待状态,处于等待的线程让出CPU的执行权利, 如果没有设置等待时间,那就只能用notify()或notifyAll进行唤醒(唤醒后进入锁定状态).

(9)sleep和wait的区别:

sleep方法来自于Thread类,wait方法来自于object;
调用sleep方法在线程中都可以用,wait就必须在同步方法或同步快中;
sleep不会释放对象锁,wait可以进行解锁,线程会释放执行的权利.

14.计算机网络编程

(1)计算机网络:

1.网络的概念

把不同地域不同计算机与专门的外部设置,用通信线路进行连接,形成一个规模大、功能强大的网络系统.可以让计算机非常方便的传递信息.

2.网络的主要功能:

资源共享-->
信息的传递和处理-->
综合信息服务-->

(2)网络通信协议

1.网络通信协议的定义

计算机网络要实现通信功能就必须要遵循一定的协议和规范,对传输的速率、内容等进行标准的定制.

2.网络通信的接口

为了使两个节点能进行对话,就必须在它们之间建立一个通信渠道(接口-->软件).
接口的目的就是用于数据的交换.
满足两个条件: 硬件装置-->实现两个节点之间的连接;
软件装置-->按照一定约束条件(通信协议)进行对话.

3.通信协议的分层思想:

两个设备要进行信息传递,底层是有很多的协议和规范,需要对这些内容进行分层处理 为什么要分层:
两个节点之间的联系非常复杂,在指定协议的时候,将整个流程分解为多个步骤,再将各个步骤结合起来.最常用的就是分层的思想.
在通信的过程中,上一层会调用下一层,每一层都在处理简单的业务,利于进行维护.

(3)OSI参考模型:

应用层--表示层--会话层--传输层--网络层--数据链路层--物理层
每一层都在处理自己的业务
TCP/IP模型:
应用层--应用程序
传输层--网络协议 TCP/UDP
网络层--IP地址/端口
物理链路层--物理介质 网线/光纤/路由器
IP:提供了唯一的IP地址,能够区分每一台主机.IP协议就位于网络层,
IP地址一共分为4段,每一段都是一个字节,每个网段最大的数字不能超过255.

(4)TCP和UDP

TCP:专门设计用来在因特网上提供可靠的连接协议,端到端的字节流通信协议, 是一种面向连接点的协议.
UDP:在发送数据的时候,不需要建立连接,封装了原始IP数据段的方法,不会去管接收方有没有接收到数据.-- 发送电报。是一种不可靠的协议
区别:TCP提供了三次握手的机会,要发送之前先和对象建立连接.
TCP类似于打电话,首先需要拨通对方的电话,等待对方的回应,继续发送信息.
是一个安全可靠的协议,但是效率就比较低.
DDP:不可靠的协议,只管发送内容不会建立连接,发送的数据就不管后面的内容,但是效率高传输速度快.

(5)端口

端口是用来区分一台计算机上的不同应用程序,在计算机内部占两个字节,一台计算机最多有65536个端口.
一个程序可以占用多个端口.一旦某个端口被占用了,另外的程序就不能再使用这个端口.
我们编写程序用到的端口必须是1024以上的端口号,1024以下的端口号系统经常调用.

(6)socket编程

一般意义上的网络编程都是指socket编程(cocket中文释义为插座).
如果两个程序要进行通信,可以通过一个双向链路进行连接实现数据的交换.双向链路的一端就称为socket.
socket是用来实现 clinet(客户端)------server(服务器) 连接.
java.net 里面提供了两个类,socket serversocket.用来实现连接.
通过socket建立连接,必须要指定IP和端口.

1.serversocket服务器端

1.创建一个serversocket对象,绑定监听端口;
2.用accept方法监听客户端的请求;
3.建立连接后,通过输入流读取到客户端的信息;
4.通过输出流往客户端发送内容;
5.关闭资源。

public static void main(String[] args) {
    ServerSocket ss = null;
    Socket s = null;
    InputStream in = null;
    InputStreamReader re = null;
    BufferedReader buff = null;
    OutputStream out = null;
    PrintWriter pw = null;
    try {
        ss = new ServerSocket(9000);
        while (true) {
            s = ss.accept();

            //接收来自客户端的信息
            in = s.getInputStream();
            re = new InputStreamReader(in);
            buff = new BufferedReader(re);
            String mesg = null;
            while ((mesg = buff.readLine()) != null) {
                System.out.println("客户端的消息:" + mesg);
            }
            s.shutdownInput();

            //向客户端发送消息
            out = s.getOutputStream();
            pw = new PrintWriter(out);
            pw.write("欢迎访问***服务器");
            pw.flush();
            s.shutdownOutput();
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) {
                out.close();
            }
            if (pw != null) {
                pw.close();
            }
            if (in != null) {
                in.close();
            }
            if (re != null) {
                re.close();
            }
            if (buff != null) {
                buff.close();
            }
            if (s != null) {
                s.close();
            }
            if (ss != null) {
                ss.close();
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
}   

2.客户端:

1.创建socket,指定服务器的IP和端口;
2.连接成功后通过输出流往服务器传递数据;
3.通过输出流获取到服务器的信息;
4.关闭相应连接。

public static void main(String[] args) {
    try {
        //连接到服务器
        Socket s = new Socket("127.0.0.1", 9000);

        //接收来自客户端的信息
        OutputStream out = s.getOutputStream();
        PrintWriter pw = new PrintWriter(out);
        pw.write("XXX访问服务器");
        pw.flush();         
        s.shutdownOutput();

        //向客户端发送消息
        InputStream in = s.getInputStream();
        InputStreamReader re = new InputStreamReader(in);
        BufferedReader buff = new BufferedReader(re);
        String mesg = null;
        while((mesg = buff.readLine()) != null){
            System.out.println("服务器提示:"+mesg);
        }
        s.shutdownInput(); //关闭输入流

        //关闭相应的连接
        in.close();
        re.close();
        buff.close();
        out.close();
        pw.close();
        s.close();

    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

15.反射

(1)类和对象的关系

类是对象的抽象,对象是类的实例具现.类体现了面向对象的抽象特征.
在java在中,静态变量和变量-->对象. 也提供了包装类来将基本数据类型转换成对象.
类产生的实例称为对象,但是类它本身也是一个对象. -->public class dog(){ } 是java.lang.class类的实例对象.
getName()-->以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称.
class类对象只有java虚拟机能够产生,不能直接实例化class.-->类类型(class type),数据类型就是class.
通过类类型产生类的实例:
第一步:Class s1 = Student.class; /Class s2 = s.getClass(); /Class s3 = Class.forNanme("全路径").
第二步:Student stu = (Student) s1.newInstance();

(2)静态加载类

编译时就对当前这个类里面所有对象进行加载,加载的对象必须存在,并且没有错误.
缺陷:要对整个系统都进行判断,只要存在 new 关键字,都必须创建实例,不能灵活的操作.编译的效率较低.

(2)动态加载类

编译时不会加载类,运行时再装载.
优点:编译时不会花很多时间去创建对象,也不会因为对象错误而加载失败,利于程序的扩展,更方便于后期的维护;
缺点:效率较低,每次都要通过路径去加载类的实例.
类的反射-->动态加载类。

(3)通过类类型获取到方法和变量的信息

1.获取到方法信息

public static void getFunMesg(Object o){
    Class c = o.getClass();
    c.getName();
    c.getSimpleName();
    Method [] m = c.getMethods(); //获取类中的所有public方法
    m = c.getDeclaredMethods();//获取到该类自己声明的方法
    for (Method method : m) {
        System.out.print(method.getName());

        //获取到方法的参数类型
        Class[] para = method.getParameterTypes();
        for (Class class1 : para) {
            System.out.print(class1.getName()+" ");
        }           
        method.getReturnType(); //获取方法的返回类型
    }
}    

2.获取到变量的信息

public static void getMesg(Object o){
    Class c = o.getClass();     
    Field [] fs = c.getDeclaredFields();
    for (Field f : fs) {
        f.getType(); //获取变量的类型
        f.getName(); //获取变量的名字          
        try {
            f.get(o); //获取到非私有的变量值  

            //设置String类型变量的值
            if (f.getType().toString().contains("String")) {
                f.set(o, "设置变量的值");
            }               
        } catch (Exception e) {
            e.printStackTrace();
        }
    }       
}  

16.面向对象的设计原则和模式

(1)理解设计原则

面向对象的设计原则OOPS(面向对象程序设计系统)编程的核心:继承、封装、多态、抽象。
设计原则就是追求高类聚、低耦合:
程序设计的时候追求模块的独立性,也就是每个模块只完成特定的功能,并且与其他模块的联系最少。如果有接口那也要接口尽量简单。

1.耦合性

1.耦合性也称为块间的联系,指的是软件系统中,各模块之间的联系紧密度。模块间联系越多耦合性越强,联系越少耦合性越弱。模块的耦合性多少取决于接口的复杂程度,调用方法、传递参数的多少。

2.类聚度:

类聚度又称为块内的联系,是模块功能强度的一个度量。即一个模块内部内部各个元素之间彼此结合的紧密度。
一个模块内各个元素包含语句、方法变量,其联系越紧密则它的类聚度就越高。

(2)常见的设计原则:

单一原则、里氏替换原则、开闭原则、依赖倒转、迪米特法则、合成/复用原则、接口隔离原则。代码复用

1.单一原则:

就一个类而言,应该仅有一个引起它变化的原因。一个类要单纯,只完成自己特定的功能。
例如:Student类中的T1、T2两个模块,若修改了T1就会影响到T2,可能会让原本正常运行的功能发生错误。
解决方案:遵循单一原则,分别建立两个类各自完成T1和T2的功能,这样的话当扩展T1模块时就不会影响T2模块。
若一个类的功能太多了,可能导致影响到其他功能。

2.里氏替换原则:

子类必须能够替代它的父类,也可以说子类可以扩展父类没有的功能,但却不能改变父类的功能。
这个原则是开闭原则的基础,有了此原则才能存在继承的设计理念,从而实现功能的扩展。

3.开闭原则:

软件实体(类、方法、函数)应该可以扩展,但是不能修改。
来源:在软件的发展周期中,因为功能变化或升级会导致业务越来越多、越来越复杂,在维护程序的时候,
可能改变原来的旧代码,可能使得需要对整个程序的架构进行重构,重构之后还需再次测试。
解决方法:当软件需要改变的时候,我们只是对程序进行扩展,而不应该对已经存在的代码进行修改。

4.依赖倒转原则:

1.高层模块不应该依赖于低层模块,都应该依赖于抽象;
2.抽象不应该依赖于细节,细节应该依赖于抽象。
高层模块实际上就是调用端,低层模块指的是具体的操作类。
抽象指的是抽象类或接口,都不能直接被实例化;细节指的是具体的实现类,可以直接被实例化。
依赖倒转的核心就是进行面向 接口/抽象类编程。

public interface IVideo {
    public void run();
}   
public class VideoPlayer {  
    //视频播放器程序
    public void play(IVideo v){
        v.run();
    }
}
 public class VideoAVI implements IVideo{
    @Override
    public void run(){
        System.out.println("播放avi视频");
    }
}  
public class VideoMP4 implements IVideo{
    @Override
    public void run(){
        System.out.println("播放MP4视频");
    }
}
public class VideoWMV implements IVideo{
    @Override
    public void run() {
        System.out.println("播放WMV视屏");      
    }
}
//程序执行入口
public static void main(String[] args) {
    VideoPlayer p = new VideoPlayer();
    VideoMP4 mp = new VideoMP4(); //接口的引用指向实现类的实例
    p.play(mp);     
    IVideo vi = new VideoAVI(); //接口的引用指向实现类的实例
    p.play(vi);     
    IVideo wmv = new VideoWMV(); //接口的引用指向实现类的实例
    p.play(wmv);        
}

5.合成/聚合复用的原则:

尽量使用合成、组合,避免使用继承。
由来:类和类之间的关系越紧密,耦合度越高,当其中一个发生变化,会影响到另一个。
用到了继承之后,两个类之间的耦合度就很高。
在设计dao层的时候,工具包尽量选择用静态方法和静态属性,避免用继承的方式去实现功能。

6.接口隔离原则:

接口隔离指的是,若一个类不需要接口就尽量不去实现接口。
接口的功能一个单一,不应该太复杂。
原因:一个接口包含多个功能,而实现类只需要其中的某一个功能。
接口一定要设计好,因为若是某个类实现了接口,那就必须实现里面的所有方法。

7.迪米特法则:

若两个类彼此之间不直接通信,则这两个类就不应该发生直接关系。如果类需要和另一个类建立关系,应该通过第三方纽带来联系。
不要和陌生程序发生联系。

public class subComp {
    public List<SubEmp> getAllEmp(){
        List<SubEmp> subEmpList = new ArrayList<SubEmp>();      
        for (int i = 0; i < 10; i++) {
            subEmpList.add(new subEmp("子公司员工"+(i+1)));
        }           
        return subEmpList;
    }       
    public void printEmp(){
        List<SubEmp> subList = getAllEmp();
        for (SubEmp subemp : subList) {
            System.out.println(subemp.getId());
        }
    }
}  
public class headComp {
    public List<Emp> getAllEmp(){
        List<Emp> empList = new ArrayList<Emp>();           
        for (int i = 0; i < 10; i++) {
            empList.add(new Emp("总公司员工"+(i+1)));
        }   
        return empList;
    }               
    public void printEmp(subComp sub){
        //得到子公司的员工数据,是通过子公司获取,而不是在总公司中直接获取
        sub.printEmp();
        //总公司的员工数据,在本类中直接获取
        List<Emp> empList = getAllEmp();
        for (Emp emp : empList) {
            System.out.println(emp.getId());
        }
    }
}

(3)设计模式 -->代码结构

设计模式就是一套被反复使用的,被很多人所知道的,多代码进行分类,对架构进行总结的一些经验总结。
为什么使用? -->使用设计模式可以重用代码,让代码更利于被人理解,保证了程序的可靠性。
工厂模式、单例模式、代理模式、装饰器模式、适配器模式、观察者模式。

1.单例模式:

什么是单例模式? -->某个类只有一个实例,只产生一个对象;这些类可以自己实例化;这个了对整个系统来说是可见的。
怎么实现单例模式? 饿汉式/懒汉式
1.设置构造器为私有的(private);
2.产生一个实例对象,并设置其属性为静态;
3.创建一个公共的静态方法。

a.饿汉模式:

优点:写起来简单,不存在多线程同步的问题,线程安全,效率比较低。
缺点在于:当类被加载时就初始化静态变量,创建并在内存中分配空间,在该类被卸载前都会一直消耗这块内存,不利于系统优化。

public class Singletion {       
    private Singletion(){           
    }       
    private static final Singletion s = new Singletion;

    public static Singletion getSingletion(){
        return s;
    }
}
b.懒汉模式

优点:写起来简单,加载类的时候不会创建实例,也就不会占用内存的静态空间,在调用的时候才创建并分配内存;
缺点:并发环境下(多线程),可能会产生多个实例,线程不安全,效率较高。
若要保证线程安全可以给方法加同步锁。

public class Singletion {       
    private Singletion(){           
    }       
    private static Singletion s;        

    public static Singletion getSingletion(){
        if (s == null) {
            //使用同步块,在创建对象的时候,只有一个线程能够操作
            synchronized (Singletion.class) {
                s = new Singletion();
            }
        }
        return s;
    }
}  

2.工厂模式

工厂模式就是将大量的有共同接口的类进行实例化的一种设计模式。
生成大量有共同接口的对象,要产生对象的时候,只需要下达命令,不需要知道工厂是如何创建的类。   

转载于:https://www.cnblogs.com/lzx007/p/6853883.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值