java SE教程09
来源:互联网 发布:网络英语教育 编辑:程序博客网 时间:2024/05/16 11:36
方法的递归调用 熟练
在编程语言中, 递归指的是一个运算过程 , 说的是, 方法不断调用自身 , 直到运算的结果已知 !
递归的好处:
递归可以大幅度的简化代码 !
缺点:
在可以使用循环的案例中, 建议不要使用递归 ! 递归极易造成 栈内存溢出(StackOverflowError)的问题 !
为了避免递归的缺点, 使用原则:
1. 递归必须有退出的条件(出口)2. 在使用递归时, 一定是把问题变得简单了, 而不是因为使用递归显得复杂了 !
需求:
递归实现阶乘: 计算5的阶乘1*2*3*4*5
public static int haha(int n){
if(n==1){
return 1;
}
return n*haha(n-1);
}
//120
public static int haha(int 5){
if(5==1){
return 1;
}
return 5*haha(5-1);
}
haha(5-1): 24
public static int haha(int 4){
if(4==1){
return 1;
}
return 4*haha(4-1);
}
haha(4-1): 6
public static int haha(int 3){
if(3==1){
return 1;
}
return 3*haha(3-1);
}
haha(3-1): 2
public static int haha(int 2){
if(2==1){
return 1;
}
return 2*haha(2-1);
}
haha(2-1): 1
public static int haha(int 1){
if(1==1){
return 1;
}
return 2*haha(2-1);
}
封装,私有 重点
在说封装之前, 先观察如下代码:
public class Demo3{
public static void main(String[] args){
Person p = new Person();
p.name = “董飞”;
p.age = -18;
p.say();
}
}
class Person{
String name;
int age;
void say(){
System.out.println(“我是:”+this.name+”,我今年”+this.age+”岁了”);
}
}
上述的程序 输出的结果为: 我是:董飞,我今年-18岁了
上述的程序, 并不存在语法错误 , 但是出现了逻辑问题, 年龄小于了!
为了避免我们在调用时, 传递的错误数据的问题 , 可以尽量的避免自己直接触碰对象中的属性:
public class Demo4{
public static void main(String[] args){
Person p = new Person();
p.setName(“董飞”);
p.setAge(18);
p.say();
}
}
class Person{
String name;
int age;
void setName(String name){ this.name = name;}void setAge(int age){ if(age<1||age>120){ System.out.println("因为数据超出了范围, 所以设置为了1岁"); this.age = 1; }else{ this.age = age; }}void say(){ System.out.println("我是:"+this.name+",我今年"+this.age+"岁了");}
}
上述的案例, 解决了逻辑问题的产生, 但是并不能阻止别人通过对象.属性去访问age , 接下来通过封装, 让外部找不到age属性 !
封装的实现(private)
public class Demo4{
public static void main(String[] args){
Person p = new Person();
p.setName(“董飞”);
//p.setAge(-18);
p.age = -18;
p.say();
}
}
class Person{
private String name;
private int age;
void setName(String name){ this.name = name;}void setAge(int age){ if(age<1||age>120){ System.out.println("因为数据超出了范围, 所以设置为了1岁"); this.age = 1; }else{ this.age = age; }}void say(){ System.out.println("我是:"+this.name+",我今年"+this.age+"岁了");}
}
封装的总结
封装可以避免很多的逻辑BUG ,
封装的关键字: private , 可以用来修饰成员属性 和 成员方法, 修饰过的成员, 只能在当前类中直接访问 !
编程规范:
1. 如果属性不是常量, 必须私有private , 确保外部的调用者无法直接赋值!2. 需要根据封装的属性, 提供供外部间接访问的方法 (读/写) - 获取属性的方法规范: 返回值类型与属性类型相同 , 方法名称为: get属性名, 并且属性名称首字母大写 例如: String getName(){ return this.name; } int getAge(){ return this.age } - 设置属性的方法规范: 没有返回值, 形式参数列表, 需要一个与属性相同名称, 相同类型的参数 ! 方法名称为set属性名, 属性名称首字母大写 例如: void setName(String name){ this.name = name; } void setAge(int age){ this.age=age; }3. 再构造方法中 , 也建议通过setXXX进行赋值 !
封装学习完毕后, 设计一个Person类
Bean类 (模型类,基本类)
1. 所有的属性, 必须私有
2. 必须存在无参构造器
3. 所有的私有属性, 必须存在set与get方法
class Person{
private String name;
private int age;
private char sex;
//构造方法Person(){}Person(String name,int age,char sex){ this.setName(name); this.setAge(age); this.setSex(sex);}//get与set方法void setName(String name){ this.name = name;}String getName(){ return this.name;}void setAge(int age){// p.age = xxx; this.age = age;}int getAge(){//p.age return this.age;}void setSex(char sex){ this.sex = sex;}char getSex(){ return this.sex;}
}
Person p = new Person();
Person p2 = new Person();
static静态 重点
静态修饰的方法和属性, 在类加载时, 就存在方法区了!
而未通过静态修饰的方法或属性, 依赖于对象, 对象创建时, 方法和属性才可以使用!
静态是依赖于类的, 类加载时, 静态的属性与方法就加载到了方法区 !
无论存在多少个对象 , 静态的方法/属性, 永远在内存中只有一份(所有对象公用)
静态不能访问非静态 , 非静态可以访问静态 !
静态: 1. 静态方法中 2. 静态代码块中 3. 静态属性 4. .. 静态内部类很容易编写代码时. 违反规则的非静态内容: 1. 在静态方法中 给 非静态属性赋值 ! 2. 在静态方法中 使用 this关键字
静态属性, 属于对象共有的案例:
class Person{
static String city;
private String name;
private int age;
void setName(String name){
this.name = name;
}
String getName(){
return this.name;
}
void setAge(int age){
this.age = age;
}
int getAge(){
return this.age;
}
void say(){
System.out.println(“我是”+name+”,我今年”+age+”岁了,我来自”+city);
}
}
代码块 熟练掌握
代码块优先级:
静态代码块 –> 构造代码块 –> 构造方法
Java中 {} , 大括号 中属于代码块
之前我们编写过类的代码块 , 方法的代码块, 构造方法的代码块
class XX{
}
void say(){
}
Person(){
}
构造块:
类似构造方法(构造器) , 每次创建对象, 构造块都会执行!
编写的方式: 在类中 直接编写代码块 (成员位置) ! 可以编写多个 !构造块 , 每次创建对象, 构造块都会执行!一般我们在构造块中, 完成一些对象初始化的操作 !this 表示新创建的对象 !例如: class Person{ {// } private String name; private int age; get/set... }
案例:
记录一个类 创建了几个对象:
public class Demo8{
public static void main(String[] args){
Person p1 = new Person();
Person p2 = new Person();
Person p33 = new Person();
Person p3 = new Person();
Person p44 = new Person();
Person p5 = new Person();
Person p6 = new Person();
Person p7 = new Person();
Person p77 = new Person();
Person p777 = new Person();
Person p888 = new Person();
Person p8 = new Person();
Person p88 = new Person();
Person p12 = new Person();
Person p13 = new Person();
Person p15 = new Person();
System.out.println("Person类一共创建了"+Person.count+"次对象"); }}class Person{ private String name; private int age; static int count = 0; Person(){ count++; } Person(String name,int age){ this.name = name ; this.age = age; count++; }}
静态代码块:
语法: 与构造块 编写基本相同, 只需要再大括号的开始, 添加static关键字即可: 静态块什么时候执行: 类加载时, 静态块就会执行 , 并且只会执行一次 !作用: 用来给类中的(static)信息进行初始化!例如: class Person{ static int count = 0; static{ //使用20行代码 ! 查询上次关闭时保存的数量 } }
普通代码块:
就是很普通的给代码分区域:再可执行的代码位置, 编写大括号 {}案例: class Demo{ public static void main(String[] args){ {//普通代码块 } {//普通代码块 } }}
单例设计模式(重点)
单例: 一个类只有单个实例!
如果构造方法可以被调用, 则可以被创建多个对象
解决方案: 构造方法私有化 (使用private修饰)
因为构造方法被私有, 只有在类的内部才可以创建对象 , 在类的内部, 私有一个静态的类对象的引用!
向外部提供一个可以获取这个对象的方法
单例设计模式
- 实现1. 饿汉式 class Single{ private Single(){} private static Single s = new Single(); static Single getInstance(){ return s; } }- 实现2. 懒汉式 class Single{ private Single(){} private static Single s; static Single getInstance(){ if(s==null){ s= new Single(); } return s; } }
懒汉单例 与 饿汉单例的区别:
饿汉是在类加载时, 就创建了对象, 等待调用方法返回这个对象 !懒汉在类加载时, 并未创建对象, 在第一次调用获取方法时, 进行了对象的创建 !
继承 重点
继承发生在类与类或接口与接口之间 !
Java语言不支持多继承,但是支持多重继承,一个类只能继承一个父类。但一个父类可以有多个子类。
Student继承自Person的案例:
人的特征:
年龄, 姓名
人的行为:
说话
学生的特征:
年龄, 姓名, 学号, 学校信息
学生的行为:
说话, 学习 !
人:
class Person{
private int age;
private String name;
Person(int age,String name){
this.age = age;
this.name = name;
}
void setAge(int age){
this.age = age;
}
int getAge(){
return this.age;
}
void setName(String name){ this.name = name;}String getName(){ return this.name;}void say(){ System.out.println("我是:"+name+",我今年"+age+"岁了");}
}
//学生
class Student extends Person{
Student(){
super(0,null);
}
//学号
private int id;
//学校
private String school;
void setId(int id){
this.id = id;
}
int getId(){
return this.id;
}
void setSchool(String school){ this.school = school;}String getSchool(){ return this.school;}void learn(){ System.out.println("我的学号是:"+id+",我来自"+school);}
}
构造方法
子类的构造方法中 隐式的调用了 父类的无参构造器 !
调用父类的构造器的原因在于, 需要创建属于父类的属性 !
我们可以显式的指定具体调用的父类构造方法!
super表示当前对象的 父类对象的引用!
Eclipse下载
打开官网下载安装包: eclipse.org
解压使用(路径不可以出现中文)
jvm找不到
1. jdk版本与eclipse不一致!2. jdk位数与eclipse不一致,例如: 32位的jdk 64位的eclipse
- java SE教程09
- java SE教程04
- java SE教程05
- java SE教程06
- java SE教程07
- java SE教程08
- java SE 教程 10
- java SE 教程 day11
- Java SE 09_Generics
- java se 09
- 新书上架:《Java SE 实践教程》
- JAVA SE — Day 09
- 教程:Win平台下配置Java SE Development Kit环境
- java se
- Java SE
- java se
- java se
- java se
- Spring MVC的数据绑定
- window下python安装包问题小结
- Mybatis学习一
- MyEclipse创建Maven多模块项目,webapp项目
- 正则表达式—Email
- java SE教程09
- Marriage Match II HDU
- MAPPER解析
- js转换成时分秒,和日时分秒的格式
- 【51Nod1274】最长递增路径
- NOIP模拟 Game 【博弈论】【动态规划】
- 从一个网址中提取视频转换成Mp3
- 区间DP
- 第八届Nuist程序设计大赛 题解