现实世界存在的任务事物都可以称之为对象,面向对象是对现实世界建模的一种方式,将一种抽象的思想给具体实例化,对象中包含的内容特征是它的属性,对象的一些操作行为是它的方法。例如简历就是一个对象,里面的内容是它的属性,看、拿、放都可以称为这个对象的方法。
封装:把描述一个对象的属性和行为封装成一个类,把具体的业务逻辑功能实现封装成一个方法,其次封装的意义还有效的保护属性通过访问修饰符私有化属性(成员变量),公有化方法。
继承:实现代码的复用,所有的子类所共有的行为和属性抽取为一个父类,所有的子类继承该类可具备父类的属性和行为,继承具有单一性和传递性。
多态:程序中定义的引用类型变量所指向的具体类型和调用的具体方法在程序编译阶段无法确定,而是在运行期才能确定该引用类型变量指向具体哪个对象而调用在哪个类中声明的方法。
行为多态:同一个run( ){ }方法,不同的对象调用时会有不同的实现,猫调用时是跑,鱼调用时是游,鸟调用时是飞。
对象多态:同一个对象,可以被造型为不同的类型,比如同一个人对象,可以被造型为儿子,父亲,员工等。
软件实体应对扩展开放,对修改关闭。在不修改现有代码的基础上去扩展新功能。
定义一个类,应该只有一个职责。如果一个类有一个以上的职责,多个职责耦合在一起,会导致设计的局限性以及代码的复用性。
子类型必须能够替换掉它们的父类型。子类可以扩展父类的功能,但不能改变父类原有的功能。当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
迪米特法则又称为最少知道原则,即一个对象应该对其他对象保持最少的了解,只与直接的朋友通信。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。尽量减少类与类之间的耦合。软件编程的总原则:低耦合高内聚。迪米特法则的初衷就是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。依赖倒置原则就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。
客户端不应该依赖它不需要的接口;一个类对一个类的依赖应该建立在最小的接口上。
尽量使用合成/聚合,尽量不要使用继承。原则:一个类中有另一个的对象。
内聚:每个模块尽可能独立完成自己功能,不依赖与模块外部的代码。 耦合:模块与模块之间接口的复杂程度,模块之间联系越复杂耦合度越高,牵一发而动全身。 低耦合是指减少对其他类的依赖,高内聚是指调用的方法尽量写在本类中,对一个项目来说,就是减少第三方依赖。 复制代码
final:可以用来修饰类、方法和变量(成员变量或局部变量)
finally:finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行。
以下这几种情况是不会被执行的:
finalize:finalize()是在java.lang.Object理定义的,也就是每一个对象都有这么一个方法。这个对象在gc启动时,该对象被回收的时候被调用。其实gc可以回收大部分对象(凡是new出来的对象,gc都能搞定),所以一般不需要去实现finalize的。
public static void main(String[] args) { Integer i = 10; Integer j = 10; System.out.println(i == j); //true Integer a = 128; Integer b = 128; System.out.println(a == b); //false int k = 10; System.out.println(k == i); //true int kk = 128; System.out.println(kk == a); //true Integer m = new Integer(10); Integer n = new Integer(10); System.out.println(m == n); //false } 复制代码
重载(Overloading):重载发生在本类,方法名相同,参数列表不同,与返回值无关,只和方法名、参数列表、参数的类型有关。
重写(Overriging):重写发生在父类和子类之间,一般表示父类和子类之间的关系。
抽象类:抽象类用abstract来修饰,抽象类是用来捕捉子类的通用性,它不能被实例化,只能用作子类的超类,抽象类是被用来创建继承层级里子类的模版。
接口:接口是抽象方法的集合,如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法,就像契约模式,如果实现了这个接口,那么久必须保证使用这些方法,并且实现这些方法,接口是一种形式,接口自身不能做任何事情,接口里面的方法默认都是abstract的。
参数 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 可以有默认的方法实现 | 完全抽象,根本不存在方法实现 |
实现方式 | 子类用extends关键字来继承抽象类,如果子类不是抽象类的话, 它需要实现父类抽象类中所有抽象方法,父类中非抽象方法可重写也可不重写 |
子类用implements去实现接口,需要实现接口中所有方法 |
构造器 | 抽象类可以有构造器(构造器不能用abstract修饰) | 接口不能有构造器 |
与正常Java类区别 | 正常Java类可被实例化,抽象类不能被实例化 | 接口和正常java类是不同的类型 |
访问修饰符 | 抽象方法可以用public、protected、default修饰 | 接口默认是public、不能用别的修饰符去修饰 |
main方法 | 抽象类可以有main方法,可以运行 | 接口中不能有main方法 |
多继承 | 抽象类可继承一个类和实现多个接口 | 接口能继承一个或多个接口 |
反射:反射的核心是JVM在运行时才动态加载或调用方法/访问属性,它不需要事先(写代码或者编译期)知道运行对象是谁。注意:由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么久不需要反射。
反射的用途:反射最重要的用途就是开发各种通用框架。
反射的基本实现:获得Class对象、判断是否为某个类的实例、创建实例、获取方法、获取构造器信息、获取类的成员变量、调用方法、利用反射创建数组。
java中有四种元注解:
@Retention:定义该注解的生命周期(什么时候使用该注解)
RetentionPolicy.RUNTIME:始终不会丢弃,运行期也保留注解,因此可以使用反射机制读取该注解的信息。自定义注解时通常使用这种方式。
@Inherited:定义该注释和子类的关系(是否允许子类继承该注解),如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
@Documented:一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中(注解是否将包含在JavaDoc中)
@Target:表示该注解用在什么地方(注解用于什么地方)
ElementType.TYPE用于描述类、接口(包括注解类型)或enum声明。
@Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Target({ElementType.FIELD,ElementType.METHOD}) @interface MyAnno{ public String name() default "zhangsan"; public String email() default "hello@example.com"; } //创建用户类 class User{ @MyAnno(name = "zhang") private String name; @MyAnno(name = "zhang@example.com") private String email; @MyAnno(name = "sayHelloWorld") public String sayHello(){ return ""; } 复制代码
Get:一般用于获取、查询资源信息
POST:一般用于更新资源信息
Get请求 | POST请求 |
---|---|
请求参数会显示在地址栏中 | 请求参数不会显示在地址栏中 |
请求体是空 | 请求体是请求参数 |
请求参数显示在请求首行中(GET/name=aaa) | 请求参数不显示在请求首行中(POST/ ) |
请求参数显示地址栏中【不安全】 | 地址栏不显示请求参数【相对安全】 |
请求参数放首行,http对请求首行显示1kb | 请求参数放请求体,请求体没有大小限制 |
请求参数不能通过request.setCharacterEncoding("gbk")来设置编码 | request.setCharacterEncoding("gbk")只能设置请求体的编码集 |
public class JDBCTest { /** * 使用JDBC连接并操作mysql数据库 */ public static void main(String[] args) { // 数据库驱动类名的字符串 String driver = "com.mysql.jdbc.Driver"; // 数据库连接串 String url = "jdbc:mysql://127.0.0.1:3306/jdbctest"; // 用户名 String username = "root"; // 密码 String password = "1234"; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 1、加载数据库驱动( 成功加载后,会将Driver类的实例注册到DriverManager类中) Class.forName(driver); // 2、获取数据库连接 conn = DriverManager.getConnection(url, username, password); // 3、获取数据库操作对象 stmt = conn.createStatement(); // 4、定义操作的SQL语句 String sql = "select * from user where id = 100"; // 5、执行数据库操作 rs = stmt.executeQuery(sql); // 6、获取并操作结果集 while (rs.next()) { System.out.println(rs.getInt("id")); System.out.println(rs.getString("name")); } } catch (Exception e) { e.printStackTrace(); } finally { // 7、关闭对象,回收数据库资源 if (rs != null) { //关闭结果集对象 try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null) { // 关闭数据库操作对象 try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { // 关闭数据库连接对象 try { if (!conn.isClosed()) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } } 复制代码
Model(模型),是程序的主体部分,主要包含业务数据和业务逻辑。在模型层,还会涉及到用户发布的服务,在服务中会根据不同的业务需求,更新业务模型中的数据。 View(视图),是程序呈现给用户的部分,是用户和程序交互的接口,用户会根据具体的业务需求,在View视图层输入自己特定的业务数据,并通过界面的事件交互 将对应的输入参数提交给后台控制器进行处理。 Controller(控制器),Controller是用来处理用户输入数据,以及更新业务模型的部分。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来 执行服务的调用和更新业务模型的数据和状态。 MVC架构的控制流程 1.所有的终端用户请求被发送到控制器。 2.控制器依赖请求去选择加载哪个模块,并把模型附加到对应的视图。 3.附加了模型数据的最终视图做为相应发送给终端用户。 复制代码