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){        {//普通代码块        }        {//普通代码块        }    }}

单例设计模式(重点)

单例: 一个类只有单个实例!

  1. 如果构造方法可以被调用, 则可以被创建多个对象

    解决方案: 构造方法私有化 (使用private修饰)

  2. 因为构造方法被私有, 只有在类的内部才可以创建对象 , 在类的内部, 私有一个静态的类对象的引用!

  3. 向外部提供一个可以获取这个对象的方法

单例设计模式

-   实现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下载

  1. 打开官网下载安装包: eclipse.org

  2. 解压使用(路径不可以出现中文)

jvm找不到

1.  jdk版本与eclipse不一致!2.  jdk位数与eclipse不一致,例如: 32位的jdk 64位的eclipse
原创粉丝点击