java SE教程09

方法的递归调用 熟练

在编程语言中, 递归指的是一个运算过程 , 说的是, 方法不断调用自身 , 直到运算的结果已知 !

递归的好处:

递归可以大幅度的简化代码 !

缺点:

在可以使用循环的案例中, 建议不要使用递归 ! 
递归极易造成 栈内存溢出(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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值