第一篇:达内学习心得:JDBC总结:系列笔记之四
达内学习心得:JDBC总结:系列笔记之四
参赛学员:常彦博 获奖奖项:二等奖
说明:(又花了几个小时把JDBC笔记转成了word版!笔记内容真实,都是课上及TTS上内容,不是从网上复制粘贴来的!同时也不会去刷点击率!不想评分的按F5刷新页面即可!不用选择分数,一旦选择就不能改了!也可以拿到电子版后再来评分!Q在下)1)此笔记为本人系列笔记之一:Java、Oracle、PL/SQL、JDBC、XML、HTML、CSS、JavaScript、Servlet„„
2)笔记内容整理了:JDBC(范传奇老师主讲,占笔记内容100%)。3)此笔记已打印出成品,一共19页!(不包括目录)。排版格式大部分按照毕业论文做的!有目录、章节、页眉、页脚、缩进、一二三级标题等。同时排版格式也照顾到了双面打印,所以电子版可直接双面打印,不需要调格式。
因此,本人的系列笔记平均花费20个小时以上(笔记纯手工输入)!每天的总结、排版很辛苦!之前有很多朋友拿到了我分享的笔记,因此还望各位尊重他人劳动成果(你懂得~~)。4)评选系统由于不能上传word版,所以格式、布局上不太好看,如文中的注意事项有特殊项目符号,这里显示的是字母u和字母v,有的图片也不能显示!内容太长,老是提交失败!只能一点一点发!
5)希望大家多多支持,评选结束后,我会找时间统一分享给大家所有的笔记!之前拿到过的朋友,也可以再要,因为修改、更新了很多内容。
——————————————————————————————————————————————————————————————————— 目录
一、JDBC概述 1 1.1 什么是JDBC 1 1.2什么是驱动 1 1.3 SQL lite 1 1.4如何使用Java连接某种数据库 1 1.5连接数据库并操作 1 1.6连接数据库时常见的错误 1
二、JDBC核心API 2 2.1 Connection 2 2.2 Statement 2 2.3 ResultSet 2 2.4 DriverManager 2 2.5 UUID3 2.6案例:使用JDBC连接数据库,并操作SQL语句 3 2.7案例:通过JDBC创建表 4 2.8案例:使用JDBC向表中插入数据 4 2.9遍历Student_chang表 5
三、JDBC核心API:PreparedStatement 6 3.1Statement的缺点 6 3.2PreparedStatement的优点 6 3.3案例详见第五章StudentDAO类 6
四、Connection封装 7
五、DAO 8 5.1持久类封装 8 5.2 DAO层 8 5.3 Properties类 8 5.4案例:注册系统 8
六、批处理 12 6.1批处理的优点 12 6.2 JDBC批处理API 12 6.3案例:详见8.4案例step7 12
七、事务处理 13 7.1事务特性ACID 13 7.2 JDBC中对事务的支持(API)13
八、DAO事务封装 14 8.1ThreadLocal原理 14 8.2原理图 14 8.3ThreadLocal核心API 14 8.4案例:登录系统(使用ThreadLocal实现连接共享)14
九、分页查询 17 9.1分页查询的基本原理 17 9.2为何使用分页查询 17 9.3 Oracle分页查询SQL语句 17 9.4 MySQL分页查询SQL语句 17 9.5“假”分页 17 9.6案例:分页查询 18
一、JDBC概述 1.1 什么是JDBC 1)Java的设计者希望使用相同的方式访问不同的数据库。
2)JDBC是Java用于统一连接数据库并操作数据库的一组通用接口定义(即通过一系列接口定义了访问数据库的通用API)。
3)JDBC是连接数据库的规范,不同的数据库厂商若想让Java语言可以对其操作,就需要实现一组类,这组类需要实现Java提供的这组用于连接数据库的接口,并实现其中定义的相关方法。那么不同的数据库厂商根据各自数据库的特点,去提供对JDBC的实现(实现类包),那么这组类就是该数据库的驱动包了。4)原理图:
1.2什么是驱动
简单的说就是让软件知道如何去操作硬件。1.3 SQL lite 是轻量级的数据库,常用于嵌入式。1.4如何使用Java连接某种数据库 需要两个部分:1)使用JDBC连接数据库(导入某数据库的.jar包)。
2)提供对该数据库的驱动包(使用静态方法Class.forName注册驱动)。1.5连接数据库并操作
1)打开与数据库的连接(使用DriverManager.getConnection获取连接)。2)执行SQL语句(使用Statement或者PreparedStatement)。3)得到结果。
1.6连接数据库时常见的错误
1)报错ClassNotFoundException则有两种情况: ①驱动包没导入。
②Class.forName()中的字符串拼写有误。2)报错port number,应注意:
①连接数据库时输入数据库路径时没有添加端口号。
②Oracle数据库的完整写法应为:jdbc:oracle:thin:@IP地址:端口号:数据库名 u 注意事项:Oracle数据库默认端口号1521。MySql数据库默认端口号为3306
二、JDBC核心API 2.1 Connection 接口,需导入java.sql.Connnection包,与特定数据库进行连接(会话)。2.2 Statement 接口,需导入java.sql.Statement包,用于执行静态SQL语句并返回它所生成结果的对象。1)ResultSet executeQuery(String sql)throws SQLException方法:执行给定的SQL语句(通常为静态SQL SELECT语句),该语句返回单个ResultSet对象。
2)boolean execute(String sql)throws SQLException方法:执行给定的SQL语句,该语句可能返回多个结果。如果第一个结果为ResultSet对象,则返回true;如果其为更新计数或者不存在任何结果,则返回false。详细介绍请看2.6案例注释。
3)int executeUpdate(String sql)throws SQLException方法:执行给定SQL语句,该语句可能为INSERT、UPDATE、DELETE(DML语句),或者不返回任何内容的DDL语句。返回值:①对于数据操作语句(DML语句),返回行计数。②对于DDL语句,返回0。
4)boolean execute(String sql)方法:返回结果为true、false,常用与执行表级操作的SQL语句,如建表、删表等,创建表若失败实际上是会直接抛出异常的。false:为建表成功的标志。5)exectue()方法:原则上可以执行任意SQL语句。返回true:若执行结果为一个结果集(ResultSet)。返回false:为其他信息(如影响表数据总条数等)。所以我们通常不会使用execute去执行查询语句。
6)int executeUpdate(String sql)throws SQLException方法:返回值int,返回值为当前执行的SQL语句影响了数据库数据的总条数;该方法常用与执行insert、update、delete语句。7)在底层一定会用到网络Socket和流,但我们不用关心使用字符还是字节接收,都由Statement做了。2.3 ResultSet 接口,表示数据库结果集的数据表(很像一个集合),通常通过执行查询数据库的语句生成。1)ResultSet特点:按行遍历,按字段取值。
2)它的next()方法包含了是否有下一条记录的hasnext()方法。
3)按字段取值时,getString(int)方法中的int,代表结果集的第几列,u 注意事项:这里的int从1开始,和Java对索引的习惯不同。2.4 DriverManager 它是管理一组JDBC驱动程序的类。1)Connection getConnection(String url,String user,String password)方法:静态方法,建立与给定数据库URL的连接(DriverManager试图从已注册的JDBC驱动程序集中选择一个适当的驱动程序)。
2)DriverManager如何知道某种数据库已注册的?
例如:oracle.jdbc.driver.OracleDriver类在Class.forName()的时候被载入JVM; 而OracleDriver是JDBC中Driver的子类,它被要求在静态初始化的时候要将自身驱动的信息通过DriverManager的静态方法注册进去,这样DriverManager就知道应该如何通过OracleDriver去连接该数据库了。所以之后就可以通过DrvierManager的另一个静态方法:getConnection()来根据之前注册的驱动信息获取连接了:
Connection conn=DriverManager.getConnetion(“",”“,”“);2.5 UUID UUID为通用唯一标识码(Universally Unique Indentifier)对于大数据量的表来说,UUID是存放ID最好的方式。1)Java提供的支持
UUID类:UUID.randomUUID().toString():获得一个36位不重复的字符串。2)Oracle提供的支持
函数sys_guid():获取一个32位不重复的字符串。2.6案例:使用JDBC连接数据库,并操作SQL语句 /** 连接数据库一定要捕获异常的 */ Connection conn=null;//定义在try外面是用于在finally块中关闭它,同时局部变量在使用前,一定要初始化!
try{ /** 与数据库进行连接分为两步:1)注册驱动:不同的数据库实现不尽相同,所以要使用不同数据库厂商提供的驱动包。连接不同数据库,传入的字符串不尽相同,但是目的相同,都是注册驱动。而对于驱动包路径,名字是固定的,基本上不会变的!2)根据数据库的位置(路径)以及用户名和密码进行连接 */ Class.forName(”oracle.jdbc.driver.OracleDriver“);/** 路径:不同数据库连接的路径写法不尽相同,Oracle的写法:
jdbc:oracle:thin:@HOST:DB_NAME
其中HOST包含两部分:IP地址和端口号;本机则使用localhost或127.0.0.1 */ conn=DriverManager.getConnection(”jdbc:oracle:thin:@192.168.0.20:1521:tarena“, ”jsd1304“,”jsd1304“);/** 使用SQL语句来操作数据库,若想执行SQL语句,我们需要使用一个专门处理SQL语句的类,这个类叫做Statement */ Statement state=conn.createStatement();/** user_tables是Oracle用于存储当前用户创建的所有表的信息,其中一个字段叫做table_name用户保存的表名 */ String sql=”SELECT table_name FROM user_tables“;/** 通过Statement执行查询语句,当查询完毕后,数据库会将查询结果返回,Statement会将查询结果存储到ResultSet中 */ ResultSet rs=state.executeQuery(sql);while(rs.next()){ //按行遍历,包含了是否有下一条记录的方法hasnext()/** 按字段取值;整数参数:结果集的第几列。注意:这里从1开始,和Java对索引的习惯不同 */ String tableName=rs.getString(1);System.out.println(tableName);} /** 底层一定会用到网络socket和流,但我们不用关心使用字符还是字节接收,都由Statement做了 */ rs.close();state.close();}catch(Exception e){ e.printStackTrace();}finally{ if(conn!=null){ try { conn.close();} catch(SQLException e){ e.printStackTrace();} } } u 注意事项: 养成良好的编码习惯:所有SQL关键字用纯大写,其他内容用纯小写。2.7案例:通过JDBC创建表 Connection conn=null;try{ //1 注册驱动
Class.forName(”oracle.jdbc.driver.OracleDriver“);//2 打开连接,支持import java.sql.*,但全导入较耗费性能 conn=DriverManager.getConnection(”jdbc:oracle:thin:@192.168.0.20:1521:tarena“,”jsd1304“,”jsd1304“);//3 创建用于执行SQL语句的Statement Statement state=conn.createStatement();//创建建表语句
String sql=”CREATE TABLE Student_chang(“ + ”id varchar2(36)PRIMARY KEY,“ +”name varchar2(30),“ + ”age number(2),“ + ”sex varchar2(2)“ + ”)“;//execute()方法详见2.2节
if(!state.execute(sql)){ System.out.println(”创建表成功!“);}else{ System.out.println(”创建失败!“);} state.close();}catch(Exception e){ e.printStackTrace();}finally{ if(conn!=null){
try { conn.close();} catch(SQLException e){
e.printStackTrace();
}
} } 2.8案例:使用JDBC向表中插入数据 Connection conn=null;try{ Class.forName(”oracle.jdbc.driver.OracleDriver“);conn=DriverManager.getConnection(”jdbc:oracle:thin:@192.168.0.20:1521:tarena“,”jsd1304“,”jsd1304“);Statement state=conn.createStatement();//UUID详见2.5 String uuid=UUID.randomUUID().toString();System.out.println(uuid);String sql=”INSERT INTO Student_chang VALUES('“+uuid +”','Chang',22,'1')“;
//或String sql=”INSERT INTO Student_chang VALUES(sys_guid(),'chang',23,'1')“;//判断insert语句是否成功,看返回值是否大于0,executeUpdate方法详见2.2 if(state.executeUpdate(sql)>0){ System.out.println(”插入数据成功“);} state.close();}catch(Exception e){ e.printStackTrace();}finally{ if(conn!=null){ try { conn.close();} catch(SQLException e){
e.printStackTrace();} } } 2.9遍历Student_chang表 Connection conn=null;try{ Class.forName(”oracle.jdbc.driver.OracleDriver“);conn=DriverManager.getConnection(”jdbc:oracle:thin:@192.168.0.20:1521:tarena“,”jsd1304“,”jsd1304“);Statement state=conn.createStatement();String sql=”SELECT * FROM Student_chang“;ResultSet rs=state.executeQuery(sql);while(rs.next()){ String id=rs.getString(1);String name=rs.getString(”name“);//不知第几列也可写列名 int age=rs.getInt(”age“);String sex=rs.getString(4).equals(”1“)?”男“:”女“;System.out.println(id+”,“+name+”,“+age+”,"+sex);} rs.close();state.close();}catch(Exception e){ e.printStackTrace();}finally{ if(conn!=null){ try { conn.close();} catch(SQLException e){ e.printStackTrace();} } }
三、JDBC核心API:PreparedStatement 3.1Statement的缺点
1)用Statement操作时代码的可读性和可维护性差,编写SQL语句复杂。
2)Statement操作SQL语句,每执行一次都要对传入的语句编译一次,效率比较差。3)不安全可能出现SQL注入攻击,详见9.6案例step3。
4)扩展:XSS攻击、html代码注入攻击、struts2 OGNL存在可以远程执行底层操作系统命令的漏洞。
3.2PreparedStatement的优点
1)PreparedStatement实例包含已编译的SQL语句。包含于PreparedStatement对象中的SQL语句可具有一个或多个IN参数。IN参数的值在SQL语句创建时未被指定。该语句为每个IN参数保留一个问号(“?”)作为占位符,不考虑类型。每个问号的值必须在该语句执行之前,通过适当的setString、setInt、setDouble„„等方法来提供。
2)由于PreparedStatement对象已预编译过,所以其执行速度要快于Statement对象。因此,多次执行的SQL语句经常创建为PreparedStatement对象,以提高效率。3)PreparedStatement继承于Statement,其中三种方法:execute、executeQuery、executeUpdate都已被更改为不再需要参数了。因为我们在获取PreparedStatement时已经将SQL语句传入了。所以执行就可以,不需要再传入SQL。4)PreparedStatement可以进行批量处理。5)可以防止SQL注入攻击。u 注意事项:
v 使用预编译语句,你传入的任何内容就不会和原来的语句发生任何匹配的关系,只要全使用预编译语句,你就不用对传入的数据作任何的过滤。
v 对一个表只作一个操作用PreparedStatement,效率高、方便 v 对表进行2种及以上的操作用Statement。3.3案例详见第五章StudentDAO类 „„„„„„„„ „„„„„„„„
五、DAO 5.1持久类封装
对象关系映射(ORM)使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据库中。1)表和类对应。2)表中的字段和类的属性对应。3)记录和对象对应。5.2 DAO层
1)DAO:数据连接对象(DataAccessObjects)
2)作用:将数据库中的数据转化为Java的对象并返回(即读数据),将Java的对象转化为数据库中表的一条数据(即写数据)。
3)Java对象在这里就是所谓的实体entity,DAO要达到的目的:对数据库数据的操作面向对象化。
4)实体:用Java中的对象去描述数据库中的某表中的某一条记录。
比如:Student表有字段id、name、age、sex,则对应的Java类中有Student类,属性有id、name、age、sex 5)实体类:用于对应数据库中的表。通常实体类的名字和数据库中表的名字一致。u 注意事项:实体类代表表,属性代表字段,对象代表一条数据。5.3 Properties类
用于读取“.properties”文本文件的类,导入java.util.Properties包。1)“.properties”文件是一个纯文本文件,里面定义的内容格式有要求,必须是key=value的形式,并且以行为单位。一行只记录一条数据!2)Properties类可以方便的读取properties文件,并将内容以类似HashMap的形式进行读取。3)db.properties文件里的内容如下:
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.0.20:1521:tarena
jdbc.user=jsd1304
jdbc.pwd=jsd1304 u 注意事项:读取的都是字符串!不用写双引号,无空格!
4)getProperty(String key)方法:该方法可以从properties文件中获取数据,如:jdbc.driver=oracle.jdbc.driver.OracleDriver。获取方式是将jdbc.driver以key作为参数调用方法。返回的就是等号右面的值oracle.jdbc.driver.OracleDriver了。
第二篇:达内学习心得:俄罗斯方块项目总结
达内学员:我的俄罗斯方块项目总结
获奖学员:陈启壮 所获奖项:三等奖 内容
俄罗斯方块一共三个类中间用等号隔开 软件的开发过程 明确业务需求
用自然语言,将业务功能描述清楚
...2 业务分析
找到有哪些业务对象,和图片的分析
tetris(俄罗斯方块)
|-- score 累计分数
|-- lines 销毁的行数
|-- Wall(墙 20行x10列)
|-- 20row(行)
|--10 col cell(列)
|-- tetromino(4格方块,有7种形态)
|-- 4 cell
|--nextOne 下一个准备下落的方块
|-- 4 cell 数据模型,一切业务对象转换为数字表示
场地按照行列划分为20x10格子
格子有属性row,col,color 4 类 设计
Tetris
|--int score
|--int lines
|--Cell[20][10] wall
|--Tetromino tetromino
|
|--Cell[4] cells
|--row
|--col
|--color 5 算法设计,就是如何利用数据的计算实现软件的功能
4格方块的初始形态: I S Z J L T O
就在初始数据的数值状态设计
四格方块的下落计算:就是将每个格子的row+1
就是将下落的业务功能,转换为数字计算实现
左右移动
下落流程控制:控制方块下落与墙之间的控制关系
1 合理的文字流程描述
2 分析文字描述中的功能(动作)为方法
3 用流程控制语句连接方法实现功能 严格测试结果!TestCase 左右移动流程控制
分数计算
界面的绘制
键盘事件控制
旋转流程控制
加速下降流程控制
开始流程控制(Timer)
暂停流程控制
继续流程控制
结束流程控制
首先是Cell类,最基本的类包含3个私有属性和get,set方法,重写Object类的toString输出方法,并规定格子所具有的3个移动功能 package com.tarena.tetris;//包:小写英文字母,域名倒写.项目名 /** * 最小的格子
*/ public class Cell{
private int row;
private int col;
private int color;
public Cell(int row, int col, int color){
super();
this.row = row;
this.col = col;
this.color = color;
}
public int getCol(){
return col;
}
public void setCol(int col){
this.col = col;
}
public int getColor(){
return color;
}
public void setColor(int color){
this.color = color;
}
public int getRow(){
return row;
}
public void setRow(int row){
this.row = row;
}
public void left(){
col--;
}
public void right(){
col++;
}
public void drop(){
row++;
}
public String toString(){
return row+“,”+col;
} } =============================================================== package com.tarena.tetris;import java.util.Arrays;import java.util.Timer;import java.util.TimerTask;
import javax.swing.JPanel;//是能够显示的矩形面板区域 import javax.swing.JFrame;//窗口框
import javax.swing.border.LineBorder;//实现边框 import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.KeyAdapter;import java.awt.event.KeyListener;import java.awt.event.KeyEvent;/* * 俄罗斯方块类
* 俄罗斯方块 扩展了(extends)系统的显示面板,增加了墙和
* 正在下落的方块
* */ public class Tetris extends JPanel{
public static final int ROWS = 20;
public static final int COLS= 10;
/*代表方块下落着陆的墙*/
private Cell[][] wall = new Cell[ROWS][COLS];
/*是正在下落的方块*/
private Tetromino tetromino;
/*下一个进入的方块*/
private Tetromino nextOne;
private static int score;
private int lines;
Timer timer;
private boolean gameOver = false;
private boolean pause = false;//暂停
private static final int[] SCORE_LEVEL={0,1,4,10,100};
private static final Graphics Graphics = null;
/*销毁(destory)满行*/
//
0 1 2 3 4
/*在Tetris中添加方法,检查游戏是否结束*/
public void rotateRightAction(){
tetromino.rotateRight();
if(outOfBounds()||coincide()){
tetromino.rotateLeft();
}
}
public void rotateLeftAction(){
tetromino.rotateLeft();
if(outOfBounds()||coincide()){
tetromino.rotateRight();
}
}
/*在Tetris中添加方法,检查游戏是否结束*/
private boolean gameOver(){
gameOver = wall[0][4]!=null;
return gameOver;
}
/*在Tetris中添加方法*/
public void hardDropAction(){
while(canDrop()){
tetromino.softDrop();
}
tetrominoLandToWall();
destroy();
if(gameOver()){
gameOverAction();
}
nextTetromino();
}
public void destroy(){
int lines = 0;//统计本次销毁的行数
for(int row = 0;row Cell[] line = wall[row]; if(fullCell(line)){ clearLine(row,wall); lines++;//每消除一行就累计加1 } } score += SCORE_LEVEL[lines]; this.lines +=lines; } public static void clearLine(int row,Cell[][] wall){ for(int i=row;i>1;i--){ System.arraycopy(wall[i-1],0,wall[i],0,wall[i].length); } Arrays.fill(wall[0],null); } public static boolean fullCell(Cell []line){ for(int col = 0;col if(line[col]==null){ return false;//找到空格子,这行没有满 } } return true; } public String toString(){//显示全部的墙 String str = “"; for(int row = 0;row Cell[] line = wall[row]; for(int col = 0;col Cell cell = line[col]; if(tetromino.contains(row,col)){ str +=row+”,“+col+” “; }else{ str = str + cell + ” “; } } str +=”n“; } return str; } /*4格方块下降流程 * 方块移动到区域最下方或是着地到其他方块上无法移动时,* 就会固定到该处,而新的方法快出现在区域上方开始下落。 * 如果能下降就继续下降,* 否则就着陆到墙上,并且生成(随机)下一个方块 * */ public void softDropAction(){ if(canDrop()){//如果能下降 tetromino.softDrop();//方块继续下降 }else{ tetrominoLandToWall();//着陆到墙上 destroy();// if(gameOver()){ gameOverAction(); } nextTetromino();//生产(随机)下一个方块 } } private void startGameAction(){ gameOver = false; pause = false; score = 0; lines = 0; emptyWall(); nextTetromino(); repaint(); timer = new Timer(); timer.schedule(new TimerTask(){ public void run(){ softDropAction(); repaint(); } }, 500, 500); } private void emptyWall(){ for(int row=0;row Arrays.fill(wall[row],null); } } /*清理游戏结束现场,如:停止定时器等*/ private void gameOverAction(){ timer.cancel();//停止定时器 } /*检查 方块 是否能够继续下落:到底最低部,或者墙上 * 的下方有方块,返回false不能下降,返回true可以下降 * */ public boolean canDrop(){ //检查到底部 Cell[] cells = tetromino.getCells(); for(Cell cell:cells){ if(cell.getRow()==ROWS-1){ return false; } } //检查墙上下方是否有方块 for(Cell cell:cells){ int row = cell.getRow(); int col = cell.getCol(); Cell block = wall[row+1][col]; if(block!=null){ return false; } } return true; } /*方块“着陆”到墙上,* 取出每个小cell * 找到cell的行号row和列号col * 将cell放置到wall[row][col]位置上 * */ public void tetrominoLandToWall(){ Cell[] cells = tetromino.getCells(); for(Cell cell:cells){ int row = cell.getRow(); int col = cell.getCol(); wall[row][col] = cell; } } /*生产(随机)下一个方块 * 1 下一个变为当前的* 2 随机产生下一个 * */ public void nextTetromino(){ if(nextOne==null){//第一次nextOne是null时候先生产一个 nextOne = Tetromino.randomTetromino(); } tetromino = nextOne;//下一个变为当前的 nextOne = Tetromino.randomTetromino();//随机产生下一个 if(tetromino==null){//处理第一次使用时候下一个是null tetromino=Tetromino.randomTetromino(); } } /*以格子为单位左右移动方块 * 1)如果遇到左右边界就不能移动了 * 2)如果与墙上的格子相撞就不能移动了 * 变通为: * 1)先将方块左移动,* 2)检查(移动结果是否出界),或者(重合) * 3)如果检查失败,就右移的回来 * * */ public void moveLeftAction(){ tetromino.moveLeft(); if(outOfBounds()|| coincide()){ tetromino.moveRight(); } } private boolean outOfBounds(){ Cell[] cells = tetromino.getCells(); for(int i = 0;i < cells.length;i++){ Cell cell = cells[i]; int row = cell.getRow(); int col = cell.getCol(); if(row == ROWS||col<0||col>=COLS){ return true; } } return false; } private boolean coincide(){ Cell[] cells = tetromino.getCells(); for(int i = 0;i < cells.length;i++){ Cell cell = cells[i]; int row = cell.getRow(); int col = cell.getCol(); if(row >0&&row &&wall[row][col]!=null){ return true;//重合 } } return false; } public void moveRightAction(){ tetromino.moveRight(); if(outOfBounds()|| coincide()){ tetromino.moveLeft(); } } public static final int CELL_SIZE = 25; /*在Tetris.java中添加main方法 作为软件的启动方法*/ public static void main(String []args){ JFrame frame = new JFrame(”俄罗斯方块“); int wigth =(COLS+8)*CELL_SIZE +100; int height =ROWS*CELL_SIZE +100; frame.setSize(wigth,height); frame.setLocationRelativeTo(null);//居中 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口就关闭软件 frame.setLayout(null);//取消默认布局,取消自动充满 Tetris panel = new Tetris(); panel.setLocation(45,25); panel.setSize((COLS+8)*CELL_SIZE,ROWS*CELL_SIZE); panel.setBorder(new LineBorder(Color.black)); frame.add(panel);//窗口中添加面板 frame.setVisible(true);//显示窗口时候调用paint() panel.action(); } /*动作方法,这里是让软件开始动作,*/ public void action(){ //wall[18][2] = new Cell(18,2,0xff0000); startGameAction(); //重绘方法->尽快调用paint() //startGameAction(); //this 是当前Tetris面板 this.requestFocus();//为当前面板请求获得输入焦点 //this对象就获得了输入焦点,以后任何的 //键盘输入(包括左右方向键)目标就是这个面板对象了! //addKeyLIstener添加键盘监听,监听那些按键输入了 this.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e){ int key = e.getKeyCode();//key按键 if(gameOver){ if(key==KeyEvent.VK_S){ startGameAction();//启动游戏开始流程 } return; } if(pause){ if(key==KeyEvent.VK_C){ continueAction(); }return; } //System.out.println(”Type:“+e.getKeyCode()); switch(key){ case KeyEvent.VK_RIGHT :moveRightAction();break; case KeyEvent.VK_LEFT :moveLeftAction();break; case KeyEvent.VK_DOWN :softDropAction();break; case KeyEvent.VK_UP :rotateRightAction();break; case KeyEvent.VK_SPACE :hardDropAction();break; case KeyEvent.VK_P :pasueAction();break; } //按键->方块移动方法->改变方块数据->repaint() //->尽快调用paint()->利用新数据绘制 repaint(); } private void continueAction(){ pause = false; timer = new Timer(); timer.schedule(new TimerTask(){ public void run(){ softDropAction(); repaint(); } }, 500, 500); } private void pasueAction(){ pause = true; timer.cancel(); } }); } //JPanel 类利用paint(涂画)方法绘制界面 //子类重写paint方法可以修改绘图逻辑 public static final int BORDER_COLOR = 0x667799; public static final int BG_COLOR = 0xC3D5EA; public static final int FONT_COLOR = 0; public void paint(Graphics g){ //g 代表绑定在当前面板上的画笔 //利用画笔在当前 面板上 绘制了一串字符! paintBackground(g);//填充背景 paintWall(g);//绘制墙 paintTetromino(g);//绘制当前方块 paintNextOne(g);//绘制下一个方块 paintScore(g);//绘制分数 paintTetrisBorder(g);//绘制边线 } private void paintScore(Graphics g){ int x = 12 * CELL_SIZE; int y = 5 * CELL_SIZE; Font font = new Font(getFont().getName(),Font.BOLD,25); String str = ”分数: “+score; g.setColor(new Color(FONT_COLOR)); g.setFont(font); g.drawString(str, x, y); y+=2*CELL_SIZE; str = ”行数: “+lines; g.drawString(str, x, y); if(gameOver){ str = ”(T_T)![s]再来!“; y+=2*CELL_SIZE; g.drawString(str, x, y); } if(pause){ str = ”[c]继续!“; y+=2*CELL_SIZE; g.drawString(str, x, y); }else{ str = ”[p]暂停!"; y+=2*CELL_SIZE; g.drawString(str, x, y); } } private void paintNextOne(Graphics g){ if(nextOne==null)//如果没有4格方块就返回,不绘制 return; for(Cell cell : nextOne.getCells()){ int row = cell.getRow()+1; int col = cell.getCol()+9; int x = col*CELL_SIZE; int y = row*CELL_SIZE; g.setColor(new Color(cell.getColor())); g.fillRect(x, y, CELL_SIZE, CELL_SIZE); g.setColor(new Color(BORDER_COLOR)); g.drawRect(x, y, CELL_SIZE, CELL_SIZE); } } private void paintTetromino(Graphics g){ if(tetromino==null)//如果没有4格方块就返回,不绘制 return; for(Cell cell : tetromino.getCells()){ int row = cell.getRow(); int col = cell.getCol(); int x = col*CELL_SIZE; int y = row*CELL_SIZE; g.setColor(new Color(cell.getColor())); g.fillRect(x, y, CELL_SIZE, CELL_SIZE); g.setColor(new Color(BORDER_COLOR)); g.drawRect(x, y, CELL_SIZE, CELL_SIZE); } } private void paintWall(Graphics g){ for(int row = 0;row for(int col = 0;col < COLS;col++){ Cell cell = wall[row][col]; int x = col*CELL_SIZE; int y = row*CELL_SIZE; if(cell == null){ //g.setColor(new Color(BORDER_COLOR)); // g.drawRect(x, y,// CELL_SIZE, CELL_SIZE); }else{ g.setColor(new Color(cell.getColor())); g.fillRect(x, y,CELL_SIZE, CELL_SIZE); g.setColor(new Color(BORDER_COLOR)); g.drawRect(col*CELL_SIZE, row*CELL_SIZE,CELL_SIZE, CELL_SIZE); } } } } private void paintBackground(Graphics g){ g.setColor(new Color(BG_COLOR)); g.fillRect(0, 0, getWidth(), getHeight()); } private void paintTetrisBorder(Graphics g){ g.setColor(new Color(BORDER_COLOR)); g.drawRect(0, 0, CELL_SIZE*COLS, CELL_SIZE*ROWS-1); g.drawRect(CELL_SIZE*COLS,0,CELL_SIZE*8-1, CELL_SIZE*ROWS-1); } } =============================================================== package com.tarena.tetris;import java.util.Arrays;import java.util.Random;/* * 四格方块类,有7种子类:I T S Z J L O * */ public abstract class Tetromino { public static final int I_COLOR =0xff6600; public static final int T_COLOR =0xffff00; public static final int S_COLOR =0x66ccff; public static final int Z_COLOR =0x00ff00; public static final int J_COLOR =0x0000ff; public static final int L_COLOR =0xcc00ff; public static final int O_COLOR =0xff0000; protected Cell[] cells = new Cell[4]; /*四格方块的下落,是四个格子一起下落*/ public void softDrop(){ for(int i = 0;i cells[i].drop(); } } /*向左移动一步*/ public void moveLeft(){ for(int i = 0;i Cell cell = cells[i];//引用赋值 cell.left(); } } public void moveRight(){ //增强for循环,是传统数组迭代的“简化版本”,//也称为foreach循环(foreach迭代)(java 5以后) for(Cell cell:cells){//底层实现就是经典迭代 cell.right(); } } public Cell[] getCells(){ return cells; } protected Offset[] states;//旋转的状态 protected class Offset{ int row0,col0; int row1,col1; int row2,col2; int row3,col3; public Offset(int row0, int col0, int row1,int col1, int row2, int col2,int row3, int col3){ this.row0 = row0; this.col0 = col0; this.row1 = row1; this.col1 = col1; this.row2 = row2; this.col2 = col2; this.row3 = row3; this.col3 = col3; } } private int index = 10000-1; /*向右转*/ public void rotateRight(){ index++; Offset offset = states[index%states.length]; Cell axis = cells[0];//找到轴(axis)的位置 cells[0].setRow(offset.row0+axis.getRow()); cells[0].setCol(offset.col0+axis.getCol()); cells[1].setRow(offset.row1+axis.getRow()); cells[1].setCol(offset.col1+axis.getCol()); cells[2].setRow(offset.row2+axis.getRow()); cells[2].setCol(offset.col2+axis.getCol()); cells[3].setRow(offset.row3+axis.getRow()); cells[3].setCol(offset.col3+axis.getCol()); } public void rotateLeft(){ index--; Offset offset = states[index%states.length]; Cell axis = cells[0];//找到轴(axis)的位置 cells[0].setRow(offset.row0+axis.getRow()); cells[0].setCol(offset.col0+axis.getCol()); cells[1].setRow(offset.row1+axis.getRow()); cells[1].setCol(offset.col1+axis.getCol()); cells[2].setRow(offset.row2+axis.getRow()); cells[2].setCol(offset.col2+axis.getCol()); cells[3].setRow(offset.row3+axis.getRow()); cells[3].setCol(offset.col3+axis.getCol()); } /*随机生成一个具体方法*/ public static Tetromino randomTetromino(){ Random random = new Random(); int type = random.nextInt(7);//0~6 switch(type){ case 0:return new I(); case 1:return new T(); case 2:return new S(); case 3:return new J(); case 4:return new Z(); case 5:return new L(); case 6:return new O(); } return null; } public String toString(){ return Arrays.toString(cells); } public boolean contains(int row, int col){ for(int i =0;i Cell cell = cells[i]; if(cell.getRow()==row && cell.getCol()==col){ return true; } } return false; } } class I extends Tetromino{ public I(){ cells[0] = new Cell(0,4,I_COLOR); cells[1] = new Cell(0,3,I_COLOR); cells[2] = new Cell(0,5,I_COLOR); cells[3] = new Cell(0,6,I_COLOR); states = new Offset[]{ new Offset(0,0,-1,0,1,0,2,0),new Offset(0,0,0,-1,0,1,0,2),}; } } class T extends Tetromino{ public T(){ cells[0] = new Cell(0,4,T_COLOR); cells[1] = new Cell(0,3,T_COLOR); cells[2] = new Cell(0,5,T_COLOR); cells[3] = new Cell(1,4,T_COLOR); states = new Offset[]{ new Offset(0,0,1,0,-1,0,0,1),new Offset(0,0,0,-1,0,1,1,0),new Offset(0,0,1,0,-1,0,0,-1),new Offset(0,0,0,1,0,-1,-1,0),}; } } class S extends Tetromino{ public S(){ cells[0] = new Cell(0,4,S_COLOR); cells[1] = new Cell(0,5,S_COLOR); cells[2] = new Cell(1,3,S_COLOR); cells[3] = new Cell(1,4,S_COLOR); states = new Offset[]{ new Offset(0,0,-1,0,1,1,0,1),new Offset(0,0,0,1,1,-1,1,0),}; } } class Z extends Tetromino{ public Z(){ cells[0] = new Cell(0,4,Z_COLOR); cells[1] = new Cell(0,3,Z_COLOR); cells[2] = new Cell(1,4,Z_COLOR); cells[3] = new Cell(1,5,Z_COLOR); states = new Offset[]{ new Offset(0,0,-1,1,0,1,1,0),new Offset(0,0,-1,-1,-1,0,0,1),}; } } class J extends Tetromino{ public J(){ cells[0] = new Cell(0,4,J_COLOR); cells[1] = new Cell(0,3,J_COLOR); cells[2] = new Cell(0,5,J_COLOR); cells[3] = new Cell(1,5,J_COLOR); states = new Offset[]{ new Offset(0,0,-1,0,1,0,1,-1),new Offset(0,0,0,1,0,-1,-1,-1),new Offset(0,0,1,0,-1,0,-1,1),new Offset(0,0,0,-1,0,1,1,1),}; } } class L extends Tetromino{ public L(){ cells[0] = new Cell(0,4,L_COLOR); cells[1] = new Cell(0,3,L_COLOR); cells[2] = new Cell(0,5,L_COLOR); cells[3] = new Cell(1,3,L_COLOR); states = new Offset[]{ new Offset(0,0,-1,0,1,0,-1,-1),new Offset(0,0,0,1,0,-1,-1,1),new Offset(0,0,1,0,-1,0,1,1),new Offset(0,0,0,-1,0,1,1,-1),}; } } class O extends Tetromino{ public O(){ cells[0] = new Cell(0,4,O_COLOR); cells[1] = new Cell(0,5,O_COLOR); cells[2] = new Cell(1,4,O_COLOR); cells[3] = new Cell(1,5,O_COLOR); states = new Offset[]{ new Offset(0,0,0,1,1,0,1,1),new Offset(0,0,0,1,1,0,1,1),}; } } 达内培训总结 今年的7月初我和大多数达内学员一样,兴奋的进入了达内进行培训,开始了C/C++的培训学习,转眼间4个多月已经过了,也结束了我们培训课程。虽然自己学的是软件技术专业,但自己在来达内之前也没有接触过C跟C++,既然走在了这条路上,我想我会一直走在这条路上,给自己的这四个月来说下几点: 1、端正自己学习的态度 在课程学习中如何端正自己的态度也是很重要的。在达内学习的过程中,每门课的时间都是很紧的,每天很辛苦,我也想过自己到底自己要不要学C/C++,但是自己还是保持了下来,有一个良好的心态去接受新的东西,哪些是自己懂的,哪些是自己不会的,自己还是要有一个计划,跟不上老师的讲课进度,也要试着去赶上老师的进度,调整自己的学习方法。 2、编程当作兴趣 在学习之初感觉编程很枯燥,所以自己还是要培养出对编程的兴趣。一开始其实多编程的兴趣也不是很大,只是慢慢习惯了枯燥,不是很感兴趣只要装着很感兴趣,久而久之开始对编程有了兴趣,正所谓兴趣才是最后的老师。 3、多敲敲代码 程序员是代码敲出来。在达内,每天学的东西到很多而且新的理论知识也多,然而那只是理论,和实际的应用还有很大差距,而这些差距只有在实际的代码编写中我们才能体会出来。所以还是每天坚持多敲敲多练练。总之,每天要保证一定量的代码,这样我们才会有真正水平上的提高。另外,在实际动手的过程中,还要多留心编译器错误提示,也有助于我们对语言的学习和理解。 4、多坚持一下 学习C/C++毕竟是非常枯燥的一件事情,虽然我们可以培养自己的兴趣,但是4个月的时间毕竟很让人疲劳、很累,随着时间的推移,我们刚开始时的兴奋劲也慢慢减退了,有什么感觉没什么希望,我们能做的就只有多坚持一下,忍得住寂寞,才守得住阵地,保得住成果。自己还是踏踏实实的坚持完成这4个月的学习,还一直在坚持。 其他的也没有什么要说的,一切多看自己的能力。 达内学习心得:精心总结的面向对象 参赛学员:方钱有 获奖奖项:二等奖 什么面向对象: 个人分析觉得:在程序设计里,面向对象是一种相对说法,相对于面向过程而言的; 面向“对象“:即重点在于“对象”;而面向过程:则重点在于“过程”,简单说:就是我我们看待事物在眼光上注重点不一样;比如说:我们评判一个女孩漂亮与否,有的人看重外表,有的人则看重“心灵”,只是侧重点不一样。 举个例子:把大象装进冰箱! 面向过程面向对象(注重一系列动作即过程)(注重动作所操作的承受者[“对象”]) “打开”冰箱“冰箱”打开“装入”大象“大象”装入“关闭”冰箱“冰箱”关闭 类:通俗的说类就是“一类事物的简称”,并且这些事物至少具有一点“共同的”特征.比如说:动物就是一个类 对象:就是某一类中一个具体的(就是可以具体描述出来的)东西,比如:动物(类)里的“狗”就是一个对象。(个人觉得对象相对于类而言的,因为狗又可以分好多种,‘狗’相对于‘哈士奇’是一个类,‘哈士奇’是‘狗’类的一个具体对象) 在生活中就拿描述汽车来说,我们都知道汽车都有4个轮子; 都有跑的功能 可以如下描述: 类汽车 属性: 4个轮 功能: 跑 那么怎么在Java中描述汽车这类呢? class car{ int wheel=4;//属性: 4个轮 void run(){//方法(功能): 跑 System.out.println(“是汽车都会跑”); } } 那么可见“出租车”应当是“汽车”这类的一个具体化(实实在在的例子即“实例”)对象,那自然出租车也就具备了汽车这类所具备的“共有”属性功能! 如何创建一个出租车对象呢?java中通过new关键字来创建一个类的实例即对象,也叫类的实例化,就是把类具体化成一个实例嘛! 格式:类名对象名 =mew 类名() Cartexi =newCar(); 创建了“出租车”对象(实例)之后那么它也就有了如下“自己”的属性和功能。 int wheel=4;//属性: 4个轮 void run(){//功能: 跑 System.out.println(“我是出租车我也会跑”); } 我们如何来访问对象中的它自己的属性和方法呢? 格式:对象.属性;对象.方法名();这一点也验证了面向对象编程的侧重点在于“对 象”上; texi.wheel;texi.run() ******************************************************************************* ******************************************************************************* ******************************************************************************* 1.封装: 从字面可以解读为将东西封起来再装好。要想拿到里面的东西就得有相应的方法打开,才能 拿到。 举例来说:一个房间的门如果没有上锁,那么大家都可以进去拿东西,但现在我们不想让谁 都进来拿东西,我们可以将房门上锁,只对外提供一把钥匙,只有有钥匙的人才能进来,这 就是“封装”现象! 在java程序中,“封装”现象如何实现呢? 可以这样实现:将类中的一些属性和方法用private关键字修饰,将他们“私有化(即不对 外直接公开)”,使外部其他类不能通过创建该类对象或通过类名直接访问这些属性和方法; 只对外提供公有的方法,外部其他类必须通过该类对外提供的公有方法来访问该类的相应成员;例如: class Person{ private String name;//将name属性私有化(封装)[相当于了上锁]使外部其他类不能直 接访问到 public SetName(String name){//对外提供公有方法(相当于房门钥匙)供外部其他类访问 到本类属性 this.name=name; } } 2.继承: 从字面来说继承就是子父类关系的简称,就是儿子(女儿也行,好吧)会继承老爸的一些属性和行为 在java中如何描述继承关系呢? 注意:第一得知道在java中继承是类与类之间或者是接口与接口之间才有继承关系; 通过extends关键字来描述继承关系 例如:老爸这个类 class Dad{ String sex=man; void smoke(){ System.out.println(“老子会抽烟!”); } } 那么我们怎么来让儿子这个类继承老爸这个类呢? class Son extends Dad{//通过extends关键字儿子这个类就继承老爸这个类了 String name;//定义自己的属性 String sex=man;//继承过来的属性,无须再定义,这里写出来是为了好理解 void smoke(){//继承过来的方法,无须再定义,这里写出来是为了好理解 System.out.println(“老子会抽烟!”); } void playBall(){//定义自己的方法 System.out.println(“儿子即会打球又会抽烟!”); } void somke(){//重写的方法 System.out.println(“我不抽20块以下的烟”); } void smoke(int n){//重载的方法 System.out.println(“我抽了+n+”年的烟了“); } } 那么具有继承关系的两个类有什么特点呢? 1)子类会将父类的属性和方法继承过来,当然子类也可以自己定义的属性和方法 2)当子类自己定义的方法和父类继承过来的方法相同时会发生“重写“现象! 3)父类用private关键字私有的方法是不能被继承的! 4)子类可以使用super访问父类的属性和方法 5)子类通过重写父类方法,修改父类的功能 6)子类构造器一定调用父类的无参构造器 7)构造器不能继承 3.多态: 字面意思就是多种形态,也就是说一种事物同时局部多种形态.注意:要出现多态情况,那么类和类之间一定得是继承关系,或者类和接口是实现关系 我觉得:在java中多态是相对于一个对象而言的,就是父类型引用变量引用子类对象,并 且父类型引用变量可以接受不同子类的对象 例如:拿上面的举例 Dad uncle=new Son();父类引用变量uncle即具备Son类的成员又具备父类的成员;这也称 为“向上造型”; 多态时的特点 1)多态时访问成员变量,如uncle.name; 编译时看等号左边,父类有该成员变量则编译通过,否则编译出错! 运行时也看等号左边,有则运行结果 2)多态时访问方法,如uncle.smoke() 编译时看等号左边,父类有该成员方法则编译通过,否则编译出错! 运行时看等号右边,父类有该方法,子类没有该方法执行父类方法;父类有该方法,子类也 有该方法执行子类方法 3)多态时访问静态方法 编译运行都看等号左边 ******************************************************************************* ******************************************************************************* ******************************************************************************* ********************* 4.抽象(有争议): 什么是抽象? 抽象就是不具体。 一般我们把不能具体描述的东西约定俗成为“抽象”的东西。例如:我们说一个人长得很 “抽象”,n你想你能具体形容描述出来么? 在JAVA中如何描述抽象这个概念呢? 我觉得在java中抽象类是由抽象方法而衍生出来的,为什么呢? 因为Java规定一个类中定义了抽象方法那这个类就跟着必须定义为抽象类,而不是因 为先定义抽象类再跟着规定抽象类中的方法必须是抽象的,可能最后理解的结果是一样的但 性质是不一样的(个人理解)简单说:就是有抽象方法的类一定是抽象类,但是抽象类中不 一定都是抽象方法,也可以有具体方法。 首先就是当我要在一个类定义一个方法时,暂时我不知道该方法具体功能是什么;等我想好 了我在用他实现一个功能时我再具体描述他功能,这样我们就可以将这个方法用abstract关 键字修饰定义为抽象方法 (还有一点也就是什么时候定义抽象类的?也可以说抽象类是向上抽取而来的,就是几个类 据有共同的属性和方法,不想每个类都定义一次,那么定义一个公有类(即抽象类)其他类 只要继承抽象类再重写方法就行!) 例如:我有一百块钱,现在我不知道怎么用,等我想好了在具体怎么用! abstract class Money{//因为有了抽象方法所以必须定义为抽象类 public abstract void buySomthing();//现在不知道怎么用,那就把它的功能代码体去掉 } //现在我饿了,想买东西吃了,我就知道怎么用了 class Hungry extends Money{ void buySomething(){ System.out.println(”我饿了,现在我要买东西吃!“) } } 抽象类的特点 1)抽象类不能实例化 2)抽象类可以继承抽象类 3)继承抽象类必须得重写抽象方法 5.抽象类,接口,普通类 的不同点和相同点? 1)不同点: 普通类接口抽象类 可以直接实例化对象不可以直接实例化对象不可以直接实例化对象 可以定义任何成员只能定义抽象成员方法和常量成员 方法必须定义为抽象其他和普通类相同 可以被继承类可以实现接口,且可以实现多个接口可以被继承 接口可以继承多个接口抽象类有构造方 法,接口中不能有 抽象类有普通成员变 量,接口中没有 抽象类可以有非抽象方 法,接口中不能有 抽象类可以用public、protected修饰,接口中只能public(默认public) 抽象类包含静态方法,接 口中没有 接口中的变量只能是 public static final,抽象类中可以是任意类型修饰 2)相同点:都可以用于描述(封装)事物的,内部类分为哪几种?分别如何创建对象? 分为 局部内部类,匿名内部类...3种 1)外部类名.内部类名 对象名=new 外部类名().new 内部类名() 2)外部类名.内部类名 对象名=外部类名.new 内部类名() 3)....不记得了第3种 匿名内部类 二、集合集合的定义? 集合:用来保存一组数据的数据结构 集合的父接口,实现接口,实现类,实现类的常用方法是什么?(建议以树状图画出来,便 于加深印象)。 Collectionlistset ArraylistLinkedListHashSet TreeSet 1.List集合List集合的特征是元素可重复且有序 ;我们可以把他看成是一个动态数组,一般通过下标 访问 ArrayList和LinkedList最常用的两个子类实现 1)list可以使用for循环遍历 for(int i=;i list.get(i); } 2)list的浅层复制 调用ArraryList.clone()方法 注意:不能使用list.clone(),clone()方法是Object类的方法,list是接口是不能继承Object类的2.Set集合: 不重复且无序集 遍历set只能迭代器,用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。Iterator while(it.hashnext()){ E e=it.next(); } 3)map表 Map存储数据使用key-value(键-值)对的形式存储数据的。 对于Map而言,要求key值是唯一的。value值可以重复 获取数据时,使用key可以获取其对应的value 遍历map有3种方法 1)遍历key Set for(String key:keySet){ System.out.println(”key:“ + key); //可以根据每一个key获取其对应的value值 int value = map.get(key); 2)遍历value Collection Iterator while(it.hasNext()){ int value = it.next();//不能采用 map.next() System.out.println(”value:“ + value); 注意:通过迭代器在遍历集合的过程中,不能通过集合(即不能采用 map.next())去改变集合元素数量 3)遍历键值对 Set for(Entry //获取一组键值对的键和值 String key = entry.getKey(); int value = entry.getValue(); System.out.println(key + ”=" + value); Collection接口方法的定义 这里我主要列举 Iterator iterator()方法的使用 Collection提供的方法 Iterator iterator()方法来获取迭代器 Iterator是一个接口,定义了遍历集合应有的方法。 使用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。问:boolean hashNext() 取:Object next() 迭代器可以将取出的数据删除掉 删:remove()将当前获取的元素删除掉。 注意:1)删除的是next()取出的元素。且只能删除一次! 2)调用1次next()后只能调用一次remove()! 达内学习心得:精心总结的面向对象 参赛学员:方钱有 获奖奖项:二等奖 什么面向对象: 个人分析觉得:在程序设计里,面向对象是一种相对说法,相对于面向过程而言的; 面向“对象“:即重点在于“对象”;而面向过程:则重点在于“过程”,简单说:就是我我们看待事物在眼光上注重点不一样;比如说:我们评判一个女孩漂亮与否,有的人看重外表,有的人则看重“心灵”,只是侧重点不一样。举个例子:把大象装进冰箱! 面向过程 面向对象 (注重一系列动作即过程) (注重动作所操作的承受者[“对象”]) “打开”冰箱 “冰箱”打开 “装入”大象 “大象”装入 “关闭”冰箱 “冰箱”关闭 类:通俗的说类就是“一类事物的简称”,并且这些事物至少具有一点“共同的”特征.比如说:动物就是一个类 对象:就是某一类中一个具体的(就是可以具体描述出来的)东西,比如:动物(类)里的“狗”就是一个对象。(个人觉得对象相对于类而言的,因为狗又可以分好多种,‘狗’相对于‘哈士奇’是一个类,‘哈士奇’是‘狗’类的一个具体对象) 在生活中就拿描述汽车来说,我们都知道汽车都有4个轮子; 都有跑的功能 可以如下描述: 类 汽车 属性: 4个轮 功能: 跑 那么怎么在Java中描述汽车这类呢? class car{ int wheel=4;//属性: 4个轮 void run(){//方法(功能): 跑 System.out.println(“是汽车都会跑”); } } 那么可见“出租车”应当是“汽车”这类的一个具体化(实实在在的例子即“实例”)对象,那自然出租车也就具备了汽车这类所具备的“共有”属性功能! 如何创建一个出租车对象呢?java中通过new关键字来创建一个类的实例即对象,也叫类的实例化,就是把类具体化成一个实例嘛!格式:类名 对象名 = mew 类名 () Car texi = new Car();创建了“出租车”对象(实例)之后那么它也就有了如下“自己”的属性和功能。 int wheel=4;//属性: 4个轮 void run(){//功能: 跑 System.out.println(“我是出租车我也会跑”); } 我们如何来访问对象中的它自己的属性和方法呢? 格式:对象.属性; 对象.方法名(); 这一点也验证了面向对象编程的侧重点在于“对象”上; texi.wheel; texi.run()********************************************************************************************************************************************************************************************************************************************* 1.封装: 从字面可以解读为将东西封起来再装好。要想拿到里面的东西就得有相应的方法打开,才能拿到。 举例来说:一个房间的门如果没有上锁,那么大家都可以进去拿东西,但现在我们不想让谁都进来拿东西,我们可以将房门上锁,只对外提供一把钥匙,只有有钥匙的人才能进来,这就是“封装”现象! 在java程序中,“封装”现象如何实现呢? 可以这样实现:将类中的一些属性和方法用private关键字修饰,将他们“私有化(即不对外直接公开)”,使外部其他类不能通过创建该类对象或通过类名直接访问这些属性和方法;只对外提供公有的方法,外部其他类必须通过该类对外提供的公有方法来访问该类的相应成员;例如: class Person{ private String name;//将name属性私有化(封装)[相当于了上锁]使外部其他类不能直接访问到 public SetName(String name){//对外提供公有方法(相当于房门钥匙)供外部其他类访问到本类属性 this.name=name; } } 2.继承: 从字面来说继承就是子父类关系的简称,就是儿子(女儿也行,好吧)会继承老爸的一些属性和行为 在java中如何描述继承关系呢? 注意: 第一得知道在java中继承是类与类之间或者是接口与接口之间才有继承关系;通过extends关键字来描述继承关系 例如:老爸这个类 class Dad{ String sex=man; void smoke(){ System.out.println(“老子会抽烟!”); } } 那么我们怎么来让儿子这个类继承老爸这个类呢? class Son extends Dad{//通过extends关键字儿子这个类就继承老爸这个类了 String name;//定义自己的属性 String sex=man;//继承过来的属性,无须再定义,这里写出来是为了好理解 void smoke(){//继承过来的方法,无须再定义,这里写出来是为了好理解 System.out.println(“老子会抽烟!”); } void playBall(){//定义自己的方法 System.out.println(“儿子即会打球又会抽烟!”); } void somke(){//重写的方法 System.out.println(“我不抽20块以下的烟”); } void smoke(int n){//重载的方法 System.out.println(“我抽了+n+”年的烟了“); } } 那么具有继承关系的两个类有什么特点呢? 1)子类会将父类的属性和方法继承过来,当然子类也可以自己定义的属性和方法 2)当子类自己定义的方法和父类继承过来的方法相同时会发生“重写“现象!3)父类用private关键字私有的方法是不能被继承的!4)子类可以使用super访问父类的属性和方法 5)子类通过重写父类方法,修改父类的功能 6)子类构造器一定调用父类的无参构造器 7)构造器不能继承 3.多态: 字面意思就是多种形态,也就是说一种事物同时局部多种形态.注意:要出现多态情况,那么类和类之间一定得是继承关系,或者类和接口是实现关系 我觉得:在java中多态是相对于一个对象而言的,就是父类型引用变量引用子类对象,并且父类型引用变量可以接受不同子类的对象 例如:拿上面的举例 Dad uncle=new Son();父类引用变量uncle即具备Son类的成员又具备父类的成员;这也称为“向上造型”; 多态时的特点 1)多态时访问成员变量,如uncle.name;编译时看等号左边,父类有该成员变量则编译通过,否则编译出错!运行时也看等号左边,有则运行结果 2)多态时访问方法,如uncle.smoke()编译时看等号左边,父类有该成员方法则编译通过,否则编译出错!运行时看等号右边,父类有该方法,子类没有该方法执行父类方法;父类有该方法,子类也有该方法执行子类方法 3)多态时访问静态方法 编译运行都看等号左边 ****************************************************************************************************************************************************************************************************************************************************************** 4.抽象(有争议): 什么是抽象? 抽象就是不具体。 一般我们把不能具体描述的东西约定俗成为“抽象”的东西。例如:我们说一个人长得很“抽象”,n你想你能具体形容描述出来么? 在JAVA中如何描述抽象这个概念呢? 我觉得在java中抽象类是由抽象方法而衍生出来的,为什么呢? 因为Java规定一个类中定义了抽象方法那这个类就跟着必须定义为抽象类,而不是因为先定义抽象类再跟着规定抽象类中的方法必须是抽象的,可能最后理解的结果是一样的但性质是不一样的(个人理解)简单说:就是有抽象方法的类一定是抽象类,但是抽象类中不一定都是抽象方法,也可以有具体方法。首先就是当我要在一个类定义一个方法时,暂时我不知道该方法具体功能是什么;等我想好了我在用他实现一个功能时我再具体描述他功能,这样我们就可以将这个方法用abstract关键字修饰定义为抽象方法 (还有一点也就是什么时候定义抽象类的?也可以说抽象类是向上抽取而来的,就是几个类据有共同的属性和方法,不想每个类都定义一次,那么定义一个公有类(即抽象类)其他类只要继承抽象类再重写方法就行!) 例如:我有一百块钱,现在我不知道怎么用,等我想好了在具体怎么用!abstract class Money{//因为有了抽象方法所以必须定义为抽象类 public abstract void buySomthing();//现在不知道怎么用,那就把它的功能代码体去掉 } //现在我饿了,想买东西吃了,我就知道怎么用了 class Hungry extends Money{ void buySomething(){ System.out.println(”我饿了,现在我要买东西吃!“) } } 抽象类的特点 1)抽象类不能实例化 2)抽象类可以继承抽象类 3)继承抽象类必须得重写抽象方法 5.抽象类,接口,普通类 的不同点和相同点? 1)不同点: 普通类 接口 抽象类 可以直接实例化对象 不可以直接实例化对象 不可以直接实例化对象 可以定义任何成员 只能定义抽象成员方法和常量 成员方法必须定义为抽象其他和普通类相同 可以被继承 类可以实现接口,且可以实现多个接口 可以被继承 接口可以继承多个接口 抽象类有构造方法,接口中不能有 抽象类有普通成员变量,接口中没有 抽象类可以有非抽象方法,接口中不能有 抽象类可以用public、protected修饰,接口中只能public(默认public) 抽象类包含静态方法,接口中没有 接口中的变量只能是public static final,抽象类中可以是任意类型修饰 2)相同点:都可以用于描述(封装)事物的,内部类分为哪几种?分别如何创建对象? 分为 局部内部类,匿名内部类...3种 1)外部类名.内部类名 对象名=new 外部类名().new 内部类名()2)外部类名.内部类名 对象名=外部类名.new 内部类名()3)....不记得了第3种 匿名内部类 二、集合集合的定义? 集合:用来保存一组数据的数据结构 集合的父接口,实现接口,实现类,实现类的常用方法是什么?(建议以树状图画出来,便于加深印象)。 Collection list set Arraylist LinkedList HashSet TreeSet 1.List集合 List集合的特征是元素可重复且有序 ;我们可以把他看成是一个动态数组,一般通过下标访问 ArrayList和LinkedList最常用的两个子类实现 1)list可以使用for循环遍历 for(int i=;i list.get(i);} 2)list的浅层复制 调用ArraryList.clone()方法 注意:不能使用list.clone(),clone()方法是Object类的方法,list是接口是不能继承Object类的 2.Set集合: 不重复且无序集 遍历set只能迭代器,用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。Iterator E e=it.next();} 3)map表 Map存储数据使用key-value(键-值)对的形式存储数据的。 对于Map而言,要求key值是唯一的。value值可以重复 获取数据时,使用key可以获取其对应的value 遍历map有3种方法 1)遍历key Set for(String key:keySet){ System.out.println(”key:“ + key); //可以根据每一个key获取其对应的value值 int value = map.get(key);2)遍历value Collection Iterator while(it.hasNext()){ int value = it.next();//不能采用 map.next() System.out.println(”value:“ + value);注意:通过迭代器在遍历集合的过程中,不能通过集合(即不能采用 map.next())去改变集合元素数量 3)遍历键值对 Set for(Entry //获取一组键值对的键和值 String key = entry.getKey(); int value = entry.getValue(); System.out.println(key + ”=" + value); Collection接口方法的定义 这里我主要列举 Iterator iterator()方法的使用 Collection提供的方法 Iterator iterator()方法来获取迭代器 Iterator是一个接口,定义了遍历集合应有的方法。 使用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。 问:boolean hashNext() 取:Object next() 迭代器可以将取出的数据删除掉 删:remove()将当前获取的元素删除掉。 注意:1)删除的是next()取出的元素。且只能删除一次! 2)调用1次next()后只能调用一次remove()!第三篇:达内培训总结
第四篇:达内学习心得:精心总结的面向对象
第五篇:达内学习心得:精心总结的面向对象