javase_09(面向对象总结)
1 Java的环境配置 day01 2 3 1. 环境配置有如下的三种方法: 4 a) 我的电脑属性: 从path 环境中配置 5 b) 利用临时的变量设置: set path = java的所在路径\bin%d% 6 c) 定义批处理文件 : 设置步骤如下: 7 a) set path = %cd%\H:\java\jdk1.7\bin 8 b) 9 c) start 10 11 一. java的环境搭配 12 1. 安装jdk >1.jdk是java的开发和运行环境 >2.jre是java的运行环境 13 2. 配置环境变量?为什么呢?方便在任意的目录下使用java工具 14 a. 我的电脑—属性—高级—环境变量 15 在已有的环境变量path的基础下,添加一个jdk\bin目录即可. 16 这种方法较为一劳永逸 17 技巧:为了日后修改方便,不需要总是修改path,可以首先定义一个环境变量 JAVA_HOME 把前面的路径保存下来.并且通过%JAVA_HOME%来动态的获取该变量 18 b. 也可以通过临时环境变量,通过dos控制台,使用set命令即可。 19 set path = (java的按照目录)jdk\bin;&path&; 20 21 c. 如果是在别人的电脑去完成java开发,还不想配置java环境变量.咱们可以使用批处理来完成: 22 a) 假设: a.bat 23 b) set path = %cd%jdk\bin;%path% %cd%代表获取当前目录. 24 c) 为了避免了不让它一闪而过:start. 25 26 二:转义字符 27 1.\n:换行 28 2.\t:tab键 29 3.\b:退格键 30 31 32 三: 数据运算符 33 34 & : 只有两边都为true结果为true,否则为false。 35 |:只有两边为flase才为false,否则都为true 36 ^ : 只有两边相同 结果为false,否则为true。 37 38 39 40 Java基础知识 day02 41 42 二.变量: 43 在内存中所开辟的空间将常量值进行存储、方便运算。 44 好处:该空间可以重复使用.. 45 定义格式: 46 数据类型 变量名 = 初始值 47 使用变量的注意事项: 48 1. 变量有自己的作用域 49 2. 变量不能赋空值. 50 51 基本数据类型: 52 byte int long char short double boolean float 53 引用数据类型: 54 接口 类 数组 55 56 什么时候需要定义变量: 57 当数据不确定时,或者运算后的结果需要进行下一步的操作 58 这时候就要定义一个变量将该不确定的数据进行存储。 59 60 三.运算符: 61 1. 算术运算符: 62 1. +:连接符 63 2. %取余: 任何数%2 结构非零急一 64 3. ++自增 (++a先运算后赋值 a++先赋值后运算) 65 2. 赋值运算符: 66 1. int a,b; 67 2. a=b=c = 4; 68 3. i+=4; i=i+4; 69 70 3.比较运算符: 71 特点:运算后结构非false 或true 72 == 相等于 73 74 4.逻辑运算符 75 & | ^ 这些运算符不仅仅可以代表boolean表达式,也可以进行位运算。 76 &和&&:当左边为false时,&:两边的表达式都参与运算。&&右边的表达式不参与运算。 77 |和||:当左边为true时,|:两边的表达式都参与运算。||右边的表达式不参与运算。 78 ^:两边一样结果为false。 79 80 5.位运算符 81 左移:<< 3<<2=12 3<<4 = 48 82 右移:>> 和 >>> 区别: 83 >>:右移后,空位按照移位前的最高位来填充。最高位为0,用0补。最高位为1用1来补 84 >>>:无符号右移,无论最高位是什么,都用0补。 85 86 6.负数的由来:取反+1 87 -6: 00000000 00000000 00000000 00000110 88 取反: 11111111 11111111 11111111 11111001 89 加一: 11111111 11111111 11111111 11111010 90 91 92 四.语句 93 94 判断:if 95 1. if(条件表达式){} 96 2. if(条件表达式){}else{}; 97 3. if(条件表达式){}else{} 98 99 对于第二种格式:简化形式,三元运算符 100 变量 =(条件表达式)? 表达式1 :表达式2 101 简化形式与非简化形式有如果不同: 102 解答: 简化形式因为是一个运算,所以咱们必须要有一个结果。 103 104 if(x >1) 105 Y = 100; 106 else 107 Y = 200; 108 Y =(x>1)? 100: 200; 109 注意:无论条件表达式有多复杂,只要有true ||flase 出现,则没问题.否则条件表达式会出错:if(x =1); 110 111 选择:switch(表达式) 112 113 switch(表达式) 114 { 115 case 1: 116 执行语句; 117 break; 118 case 2: 119 执行语句; 120 break; 121 case 3: 122 执行语句; 123 break; 124 default; 125 执行语句; 126 } 127 128 特点: 129 1.表达式运算四种类型的值:byet int short char(它有一个自动型转换过程) 130 2.case和default之间是可以没有任何的顺序,但是在运算期间,肯定会先读取第一个case ,当case不匹配,会继续执行其他的case。当所有的case不匹配的时候.会运行default。 131 3.switch语句结束的两个方式:a.读取switch语句大括号结束b.碰到break语句结束.注意:如果没有碰到break,也没有读取结束的时候,那么程序是一直往下面运行,直到程序运算完毕 132 133 134 135 循环:while du{}while; for 136 137 1. while(表达式){执行语句}(先判断后执行) 138 2. do{执行语句}while(条件表达式);(先执行一次,再判断) 139 3. for(初始化表达式;循环判断条件;循环后的操作表达式){} 140 141 什么时候用这些语句呢? 142 当对固定的几个值进行判断的时候,建议使用switch 143 当对范围的判断,或者对运算后的真假进行判断的时候,我们需要用到if 144 145 当需要执行语句多次的时候.我们使用到循环 146 while与for循环是可以相互交换 147 因为作用域的关系: 148 在使用两个语句的时候有些区分,如果定义变量只为循环存在,循环结束后就没有意义。我们使用到for循环语句。 149 如果变量在循环后再执行别的运算,那么我们使用while比较好~ 150 151 break:选择结构和循环结构 152 continue:循环结果:结束本次循环.继续下一次循环 153 154 函数: 155 特点: 156 --类中的一个独立小程序 157 --只有被调用的时候才会运算 158 --可以重复的去运行 159 好处: 160 对代码进行封装,可以提高代码的复用性 161 格式: 162 返回值类型 函数名(参数类型 形式参数1) 163 { 164 执行语句; 165 return 返回值; 166 } 167 168 如果定义一个函数? 169 1. 明确该功能函数运算后的结果。(明确返回值类型) 170 2. 明确该功能实现的过程,是否需要有未知值参与运算(明确函数的参数类型) 171 要定义一个加法运算功能 172 173 int getSum(int x ,int y) 174 { 175 return x + y; 176 } 177 178 方法的重载:@overload(标记重载) 179 特点:当多个函数的功能一致,只是参与运算不同的时候,为了提高代码的可阅读性,我们可以使用方法的重载.用参数来进行区分. 180 int getSum(int x,int y,int z) 181 { 182 return x + y + z; 183 } 184 185 函数的特点: 186 有一种情况,函数执行一个功能,但没有具体的返回值。返回值类型不可以具体的来确定的时候,那么我们用void关键字来表示.那么函数的return 语句是可以忽略不写的. 也可以:return ; 187 188 189 day03 数组 190 191 五.数组: 其实就是同类型的一组数字 192 193 同一种类型数据的集合,类型一定要一致。 194 195 内存图: 196 java划分了两片内存,方便了运算 197 198 栈内存:存放局部变量,函数上和函数定义的变量都是局部变量 199 变量一点使用完毕,自动清空。 200 栈内存: new关键字所建立的,都称为实例.在堆内存里面存放的. 201 202 203 数组常见的如下问题: 204 角标越界异常:使用到数组中不存在的角标。 205 (ArrayIndexOutOfBoundsException) 数组特有异常 206 207 空指针异常:引用型变量等于null,也就是没有指向。 208 (NullPointsException) 209 ######## 210 本身就是一个容器,用来存储数据. 211 特点:固定的长度. 212 好处:给元素进行编号,从零开始。同时也可以length属性获取数组的长度. 213 214 什么时候使用数组? 215 当数据较多的时候,通常是为了方便操作这些数据都需要进行临时存储. 216 217 习惯: 218 通常操作数组都需要遍历,获取数组中的元素需要一个指针。 219 通常对指针的值的改变也就是更改了数组里边的值啦~~ 220 221 222 223 选择排序: 224 int[]arr = {1,2,45,657,33,214,64,16,32,13}; 225 226 for(int i = 0;i<arr.length;i++) 227 { 228 for(int j = i+1;j<arr.length;j++) 229 { 230 if(arr[j]>arr[i]) 231 { 232 swap(arr,j,i); 233 } 234 } 235 } 236 237 冒泡排序: bubbleSort 238 239 public static int[] bubbleSort(int[]arr) 240 { 241 for(int i = 0;i<arr.length;i++) 242 { 243 for(int j = 0;j<arr.length-i-1;j++) 244 { 245 if(arr[j]>arr[j+1]) 246 { 247 swap(arr,j,j+1); 248 } 249 } 250 } 251 return arr; 252 253 254 day 04 面向对象 255 面向对象: 256 1. 符合现实中人民思考习惯的一种思想. 257 2. 它将程序员的角色(执行者)转换成(指挥者) 258 3. 将复杂的问题简单化. 259 260 对象无处不在,一切皆对象 261 262 对象是实实在在存在的个体,那么我们需要使用计算机语言来进行描述 263 在java当中,描述事物是通过类来完成,在计算机中是通过new 类来创建对象.并且指挥对象完成事情. 264 265 例如: 制造汽车,通过汽车来描述:图纸。对应的java中的类class 266 通过图纸来产生汽车: 对象,对应的就是java在堆内存中所产生的实例 267 268 通过java语言编写程序,其实就是不断的定义类,创建对象的一个过程。 269 成员变量(事物的属性) 成员方法(事物的行为)。 270 271 对象的存在有什么好处?或者说怎么才叫做对象? 272 对象可以用于封装数据.可以在对象中定义属性和行为,并指挥. 273 274 在编写程序中,当要完成某个功能的时候,先看一下java是否提供了自有的对象.如果有,那么可以直接的去使用这个对象里面的功能.否则如果该对象不存在.那么我们需要定义一个对象,并将需要的功能封装到该对象中,以便对象的重复使用.。 275 276 对象是如何使用呢? 277 通过new 关键字来建立,并且通过 对象.成员变量 的形式操作对象所做的事情.. 278 279 280 匿名对象: 281 其实就是一个没有名字的对象,可以理解为创建对象的简化形式. 282 283 1. 当只对对象方法进行一次操作的时候可以使用 284 a) new person(); 285 2. 可以做为实际参数的传递: 286 a) public void show(new Person()); 287 288 289 封装: 290 什么是封装呢? 291 其实就是隐藏实现细节,提供了安全性 292 293 在通过类来创建对象的时候,可以通过对象调用成员,也可以使用对象的属性 294 为了提高安全性,所以避免了直接对属性进行访问:我们可以把它设计为私有private 295 296 对外提供方法来间接访问age进行赋值! 297 298 private int age ; 299 public void setAge(int age) 300 { 301 this.age = age; 302 } 303 304 public int getAge() 305 { 306 retrun age; 307 } 308 在代码的体现: 309 1.函数就是一个最小的封装体 310 2.类本身就是一种封装 311 3.包也是一种封装 312 4.ssh框架也是一种封装. 313 5.timcat服务器软件 314 315 316 /* 317 318 体现良好的封装! 319 */ 320 321 class Person 322 { 323 private String name ; 324 private int age; 325 326 327 /* 328 这是隐藏下来的代码~~ 329 */ 330 Person() 331 { 332 super(); 333 } 334 public void setName(String name) 335 { 336 this.name = name; 337 } 338 public String getName() 339 { 340 return name ; //this.name 341 } 342 343 public void setAge(int age) 344 { 345 this.age = age; 346 } 347 public int getAge() 348 { 349 return age; 350 } 351 } 352 class Demo5 353 { 354 public static void main(String[] args) 355 { 356 Person p = new Person(); 357 p.setName("kudy"); 358 String name = p.getName(); 359 360 p.setAge(18); 361 int age = p.getAge(); 362 } 363 } 364 365 366 执行的过程: 367 1. 加载Person .class文件到堆内存中 368 2. 因为new,在堆内存中开辟空间,创建对象。在对象中出现了name 与age 369 3. 对象中的属性默认初始化 370 4. 对象中的属性显式初始化 371 5. 构造函数初始化 372 6. 创建引用变量,并将该对象的首地址给变量,该变量这时候就指向了对象。 373 374 375 this语句代码什么? 376 1.this所在的函数所属对象的引用 377 2.this被那个对象调用.那this就代表那个对象 378 379 A)this还可以用与区分成员变量与局部变量同名的情况 380 381 B)什么时候使用this? 382 当定义功能时,该变量内部使用了本类的对象,同时,this表示该对象 383 384 C)this语句: 385 在构造函数中,方便于构造函数调用,但注意:this语句只能在构造函数的第一位.因为要对执行的数据进行初始化. 386 387 388 389 day05 面向对象 390 1, 构造函数 391 a. 函数名与类名相同 392 b. 没有返回值 393 c. 函数中没有return语句 394 395 作用: 可以对对象进行初始化 396 397 比喻:Person p = new Person(); 398 a,加载Person.class文件到堆内存中 399 b,在堆内存中开辟空间,创建实例对象 400 c,对对象的内容进行默认的初始化 401 d,对对象的内容进行显式的初始化 402 e,对对象自定义的内容进行初始化,通过构造函数来完成的. 403 f,在栈内存中定义变量存入对象的地址值,指向该对象 404 405 注意: 406 在用class文件时,jvm会自动的在该类添加一个默认的构造函数(没有构造函数,你就创建不了对象的哦)该函数的形参是空的. 407 构造函数可以通过this来进行互相的调用,是通过this语句来完成 408 this的语句一定要放在构造函数的第一行 409 410 411 2,static关键字 412 特点: 413 ---随着类的加载而加载,随着类的消失而消失,静态成员的声明周期最长 414 ---优先于对象 415 ---被所有的对象所共享 416 ---可以直接通过类名来调用 417 418 注意: 419 ---静态方法只能访问静态的成员(因为我是不需要创建对象就可以使用的) 420 ---静态方法中不能出现this,super关键字.因为静态方法没有所谓的对象 421 ---主函数是静态的 422 423 424 2, 设计模式:解决某类问题之间有效的方法. 425 java中有23种设计模式 426 427 单例设计模式: 428 a) 私有化构造函数 429 b) 定义一个静态私有化的本类对象 430 c) 定义一个静态方法返回内部对象的地址 431 432 433 434 435 class Singleton 436 { 437 private Singleton() 438 { 439 //私有化构造函数,避免创建对象! 440 } 441 442 443 private static Singleton singleton = new Singleton(); 444 public static Singleton getSingLeton() 445 { 446 return singleton; 447 } 448 } 449 class Demo7 450 { 451 public static void main(String[] args) 452 { 453 Singleton s1 = Singleton.getSingLeton(); 454 Singleton s2 = Singleton.getSingLeton(); 455 System.out.println(s1== s2); 456 } 457 } 458 459 3,静态的代码块: 460 特点:随着类的加载而加载,执行一次,优先于函数 461 作用:对于类的初始化 462 463 464 4,内部类: 465 其实就是一个类的内部中定义另外一个类,内部类可以定义在外部类里面 466 内部类可以直接访问外部类的成员,那是因为内部类只有一个外部类的引用(类名.this)而外部类访问内部类的成员需要创建对象 467 468 什么时候使用内部类? 469 描述事物时,该事物内部与还有事物,那么可以通过内部类来完成 470 471 当内部类在成员位置上,可以被成员修饰符所修饰。 472 当内部类中定义了静态成员时,内部类是必须要静态的.但是静态内部类局限性 473 但方法中里面定义了内部类,方法里面的属性内部类是不能所访问的.因为局部变量是存储在栈内存中,系统会不知道什么时候会被释放.那么我们如果定义成final 就是没问题.定义成final就是常量.是不能改变的量.是存储在堆内存中. 474 475 476 day06面向对象(面向对象的总结) 477 478 异常: 479 480 异常的处理机制: 481 482 1.可以在方法后面使用throws关键字,声明向外抛出一个异常 483 2.可以使用try catch语句块捕获异常 484 3.finally语句块的作用: finally需要结合try使用.不论如何finally当中的代码都是会被执行 485 4.如果是运行时异常,那么jvm是自动的抛出一个异常对象.让虚拟机去处理.也可以自己手动的去处理. 486 487 自定义异常: 488 489 1.自定义编译时异常,定义一个类继承与Exception 490 2.可以在程序中使用throw关键字向外抛出一个编译时异常对象,这时方法必须向外抛出一个异常 491 throw关键字相当于return 492 493 异常的使用细节: 494 因为都是为了多态而服务的,所以当父类型的引用指向子类型的对象的时候/jvm就分辨不清楚啦~~) 495 496 1. 子类重写父类的方法.不能抛出被父类更多的方法.没抛,子类不能抛.父类抛了.子类可以不抛.要抛也只能抛父类一样的异常,或者父类异常的子类. 497 2. 一个try语句可以跟多个catch语句一起来捕获异常 498 3.try finally 可以嵌套使用. 499 500 异常的使用总结: 501 502 1.异常是在程序运算期间发生的错误,所有的异常类都是Throwable的子类 503 2.error,java的虚拟机错误,比较严重。处理不了.不用处理。编译是不会出错 504 3.Exception:异常{ 505 一个特殊的子类,RuntimeException这个类的所有的子类都是运行的时候异常,不必要处理,编译时不会报错.交给默认的处理程序.其它的子类都是编译时异常,比较严重的错误!在方法后面应该跑出去,我们在调用方法一定要处理.否则编译器会报错。 506 } 507 4.异常处理方式:try {} catch捕获异常,throws 向外抛出一个异常 508 5.thorw 与throws 的区别? 509 throws声明方法向外抛出一个异常 510 throw和return一样,只不过是要创建一个对象 511 注意: 512 抛出一个对象,一定需要在方法外面声明抛出一个异常. 513 514 6.自定义异常: 515 1.可以自己写一个类继承与Exception,这个类就是编译时异常 516 2.可以自己写一个类继承于RuntimeException,这个类就是运算期间异常 517 518 519 面试题目: 520 521 1.请说说final 与 finalize 和 finally的区别?三者有什么共同点? 522 解答: 除了单词有点像,他们都是没什么缘分的.. 523 1.final是java的修饰关键字.修饰类,类不能被继承.修饰属性.属性会编程常量.不能修改的值.修饰方法.这个方法不能被重写. 524 2.finalize:是在Object类当中定义的一个方法,所有的类都是默认继承与Object类.也就是说:继承了这个方法.当对象被垃圾回收之前.jvm会自动的调用该对象的finalize方法,所以我们一般通过finalize来做一些内存释放的工作.. 525 3.finally :java中的关键字,必须结合try语句一起来使用.写在finally代码中的语句.一定会被执行.除非jvm退出。 526 527 class MyException extends Exception 528 { 529 public String getMessage() 530 { 531 return "上帝~~"; 532 } 533 } 534 535 class Student 536 { 537 public void readBook(int num) throws Exception 538 { 539 if(num >300 || num <1){ 540 throw new Exception(){ //返回一个对象 541 //匿名内部类.重写了父类的方法! 542 public String getMessage() 543 { 544 return "你在吹牛吗?"; 545 } 546 }; 547 } 548 else 549 { 550 System.out.println("好孩子!"); 551 } 552 553 } 554 555 public void eat(int week) throws MyException //向外抛出去一个异常 556 { 557 if(week<1||week>7) 558 throw new MyException(); //结束,有了一个对象! 559 else 560 System.out.println("星期是正确的!!"); 561 } 562 } 563 class Demo10 564 { 565 public static void main(String[] args) 566 { 567 try 568 { 569 new Student().readBook(400); 570 } 571 catch (Exception e) 572 { 573 e.printStackTrace(); 574 } 575 576 577 try 578 { 579 new Student().eat(88); 580 } 581 catch (Exception e) //父类型的引用所指向子类型的对象 Exception e = new MyException(); 582 { 583 e.printStackTrace(); 584 } 585 586 } 587 } 588 589 590 1. 封装性: 591 1)类的封装:将属性都私有化(private),防止外界的直接访问,对外提供s et 与get方法。 592 优点:隐藏内部实现过程,方便权限的管理 593 594 2)方法的封装:在实现功能的时候,应该尽可能的多抽取方法,尽量将别人用不到的方法私有化,实现一个封装性。将提供方法进行功能调用方法设置为公有的public就可以 595 优点:让类看起来更加的整洁,对外隐藏了实现的细节。 596 597 2. 抽象: 598 a) 为了描述显示的事物,在程序中通过对象来映射显示中类的事物(万物皆对象) 599 b) 将一组特征相似的对象共同的特征和行为抽象出一个类来定义 600 c) 类的成员变量(属性)来描述特征,用成员方法来描述对象的行为 601 3. 继承: 602 a) 使用extends 关键字让子类继承父类,子类就可以自动复用了父类的所有属性和方法(非私有) 603 b) 子类实例化过程: 604 1. 子类的构造方法一定会调用父类的构造方法,可以在第一行使用this(实参)来调用自己其他的构造方法,使用super(实参)来调用父类的构造方法 605 2. 如果第一行没有声明,jvm会自动调用父类的无参的构造方法 606 3. 子类和父类之间的转换 607 1,可以将子类实例当做父类来用,反则不能. 608 2,把子类当做父类来用时:调用方法是子类的(重写的关系),这个是做了动态的绑定,如果是访问属性的(静态的绑定)也就说:调用的数父类的属性. 609 3,把子类当做父类来使用时,不能调用子类特有方法,因为编译器会检查语法,发现该父类没有这个方法,会报错! 610 4,如果是把子类当做父类来使用的时候,这时候可以强制类型转换,则再有把握:咱们都需要用instanceof来判断一些对象的类型。 611 4. 多态: 612 1. 把子类当做父类来用 613 2. 我们在编程无时无刻不使用多态,在定义一个方法形参的时候,为了便于方法的通用性,通常会将形参定义为父类类型,最好是接口类型,当调用方法的时候.那么就可以子类实例当做父类来使用,正因为有了多态,我们经常把子类当做父类来使用。所以有了以下的规定。 614 ii. 返回值类型必须和父类的一致,或者是父类返回值类型的子类实例 615 iii. 子类不能有比父类更加严格的访问权限,假设父类是 public 而你子类是:private 那么在传递参数的时候,有可能会因为访问权限而出错!所以java是不允许的. 616 iv. 子类不能被父类抛出更多的异常. 617 v. 异常: throw 抛出一个异常对象.方法外部也是需要向外声明抛出一个异常 618 619 620 彩票的摇奖过程: 621 622 import java.util.Random; 623 class Lottery 624 { 625 private int poorCount; 626 private int luckyPoorCount; 627 private int[] poor; 628 private int []luckPoor; 629 630 //构造函数在构造摇奖的对象 631 Lottery(int poorCount,int luckyPoorCount) 632 { 633 this.poorCount = poorCount; 634 this.luckyPoorCount = luckyPoorCount; 635 setPoor(); 636 } 637 638 //填充奖池 639 private void setPoor() 640 { 641 /* 642 怎么做? 643 1.根据poorCount创建数组, 644 2.将1~poorCount填充数组, 645 */ 646 int[] arr = new int[poorCount]; 647 for(int i=0; i<poorCount; i++) 648 arr[i] = i+1; //37个数字 649 poor = arr; 650 luckPoor = new int[luckyPoorCount]; 651 } 652 653 public void run() 654 { 655 //摇出所有的中奖号码放在中奖池中 656 setLuckyPoor(); 657 //输出所有的中奖号码 658 listLuckyPoor(); 659 } 660 661 //获得所有的中奖号码~~ 662 public void setLuckyPoor() 663 { 664 //1.定义循环,循环次数是luckyPoorCount 665 for(int i=0; i<luckyPoorCount; i++) 666 { 667 //1.产生一个随机的中奖号码 668 int luckyNumber = getLuckyNumber(); 669 //2.将中奖号码从里面删除 670 deleteNumber(luckyNumber); 671 //3.将中奖号码放在奖池中 672 luckPoor[i] = luckyNumber; 673 } 674 } 675 676 private int getLuckyNumber() 677 { 678 int randomNum = new Random().nextInt(poor.length); 679 return poor[randomNum]; 680 } 681 682 private void deleteNumber(int luckyNumber) 683 { 684 int[] newArr = new int[poor.length-1]; 685 int pos = 0; 686 for(int i=0; i<poor.length; i++) 687 { 688 if(poor[i] == luckyNumber) 689 continue; 690 newArr[pos++] = poor[i]; //幸运的数字 691 } 692 poor = newArr; 693 } 694 695 private void listLuckyPoor() 696 { 697 StringBuffer sb = new StringBuffer(); 698 for(int num : luckPoor) 699 sb.append(num +" "); 700 System.out.println("中奖的号码为:"); 701 System.out.println(sb); 702 } 703 } 704 705 public class Demo11 706 { 707 public static void main(String[] args) 708 { 709 Lottery lottery = new Lottery(36,7); 710 lottery.run(); 711 } 712 }