美文网首页
疯狂java讲义第五章笔记

疯狂java讲义第五章笔记

作者: 娄童 | 来源:发表于2016-09-26 16:56 被阅读430次

1 定义类,成员变量和方法

类和对象

定义类

java的类名由一个或者多个有意义的单词组合而成,每个单词的首字母大写,其他的全部消协,并且单词之间没有分隔符。
成员变量:用于定义该类或者实例的所包含的状态数据。
方法:用于定义该类或者实例所包含的功能实现和行为特征。
构造器:用于构造该类的实例。

  1. 定义成员变量的语法格式:
    [修饰符] 类型 成员变量名;
    1,修饰符可以没有,也可以是public ,protected,private,static,final.前三个最多出现一个,可以与static final组合起来修饰成员变量
    2,类型:任何类型,
    3,成员变量名,第一个单词的首字母小写,其他的大写,用英文名词
    4,默认值:定义成员变量可以指定一个可选的默认值。
  2. 定义方法的语法格式
    [修饰符]返回值类型 方法名(形参列表)

    //由0条或者多条可执行的语句构成的方法体

    1,修饰符:可以省略,public protected private static final abstract 前三个可以出现一个,final和abstract 只能出现其中之一,他们与static组合起来修饰方法
    2,返回值类型:任何类型。如果生命了返回值类型,必须有有效的return语句,否则用void.
    3,方法名 ,基本和成员变量的一样,最好用英文动词。
    4,形参列表:0组到多组的“参数类型 形参名,参数类型 形参名,,,”
  3. static关键字
    static修饰的成员表示他是属于类的,类变量类方法。也叫静态。静态成员不能直接访问非静态成员。
    static真正的作用是用来区分成员变量,方法,内部类,初始化块属于类本身还是属于实例。
  4. 定义构造器语法格式
    [修饰符] 构造器名 (形参列表)


    1,修饰符可以是省略,public protected private其中之一
    2,构造器名必须与类名相同
    3,与方法的相同
  5. java类的大致作用
    定义变量
    创建对象
    调用类的类方法,或者访问类的类变量

创建并使用对象

对象的产生和使用

Person p=new Person();
p.say("你真棒");
p.name(“李刚”);//直接给成员变量赋值

对象和引用

堆里面的对象可以有多个引用。
Person p1=p;
这时p1和p指向同一个对象。
如果希望通知垃圾回收机制回收某个对象,把引用变量赋值为null

this

this关键字总是指向调用该方法的对象,谁调用它,他就指向谁,就可以获取成员变量和方法。

public class Dog {
    public void jump()
    {
        System.out.println("正在执行jump方法");
    }
    public void run()
    {
        //如果想在这个方法里面调用另一个方法
        //如果没有this,则必须再创建一个对象
        //有了this,就不需要创建了,因为this就是指向调用该方法的对象
        this.jump();
        jump();
    }

static修饰的方法,是用类来直接调用的,因此不需要再创建一个对象,因此也就不使用this,因此static对象不能访问非静态成员

public class StaticAccessNonStatic {
    
    public void info()
    {
        System.out.println("简单的方法");
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new StaticAccessNonStatic().info();

    }

}

大部分时候,普通方法访问其他方法,成员变量无需使用this,但是如果方法里面有局部变量和成员变量同名,但是又需要在方法里面访问,则必须适应this
this也可以用于构造器作为默认引用。代表构造器正在初始化的对象。

public class ThisInConstructor {
    //定义一个名为foo的成员变量
    public int foo;
    public ThisInConstructor ()
    {
        // 在构造器中又定义了一个foo
        //this代表正在初始化的对象,把他的foo成员变量设为6
        int foo=0;
        this.foo=6;
    }

this还可以作为普通方法的返回值,表示返回调用该方法的对象

方法必须属于类或者对象

java里面的类不能独立存在,必须放在类里面

方法的所属性

2 java方法的参数传递机制

值传递

参数传递方式是一种值传递方式。也就是实参的副本保存在形参中。如果形参是基本类型,那么方法中对形参的修改不会改变实参;如果形参是引用类型,仍然是指传递,由于引用类型是指针,保存的是地址,所以方法中对形参的修改会改变实参的值,但是如果在方法中把形参的引用赋值为null,则实参不会改变。

class DataWrap
{
    int a;
    int b;
}

public class ReferenceTransferTest {
    
    public static void swap(DataWrap dw)
    {
        int temp=dw.a;
        dw.a=dw.b;
        dw.b=temp;
        System.out.println("在swap方法里面a是"+dw.a+"b是"+dw.b);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ReferenceTransferTest  rf=new ReferenceTransferTest();
        DataWrap dw=new DataWrap();
        dw.a=9;
        dw.b=4;
        rf.swap(dw);
        System.out.println("交换结束后a是"+dw.a+"b是"+dw.b);
    }
}

参数个数可变的方法

在最后一个形参的类型后面加上"...", 表示形参可以接受多个参数。本质上就是一个数组类型的形参。传入的实参可以是多个参数,也可以是一个数组。
但是参数个数可变的形参必须处于形参列表的最后,且只能有一个。
如果形参是数组的话,传递的方式是
test(new String[]{"abs","cps"});
如果形参时参数可变的,传递方式除了上边的方式,还可以是
test("abs","cds");

public class Varargs {
    //定义一个参数可变的方法
    public static void test(int a,String ...books)
    {
        //books被当作数组处理
        for(String tmp:books)
        {
            System.out.println(tmp);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        test(4,"ans","csd");
    }
}

3 递归方法

定义:一个方法体内调用自身。
只要一个方法的方法体实现中再次调用了自身方法,就是递归。递归必须向已知方向递归

public class Recursive {
    public static int fn(int n)
    {
        if(n==1)
        {
            return 1;
        }else if(n==2)
        {
            return 2;
        }
        else 
        {
            //方法中调用自身
            return 2*fn(n-1)+fn(n-2);
        }
        
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(fn(10));

    }

}

4 方法的重载

“两同一不同”
同一个类中方法名相同,参数列表不同。
注意被重载的方法里面包含了参数可变的形参。

public class OverloadVarargs {
    public void test(String msg)
    {
        System.out.println("只有一个形参的test方法");
    }

    public void test(String ... books)
    {
        System.out.println("多个形参的test方法");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        OverloadVarargs olV =new OverloadVarargs();
        olV.test("aa");
        olV.test("bb","cc","dd");
        olV.test();
        olV.test(new String[]{"aa"});

    }

}

5 成员变量和局部变量

必须先给方法局部变量和代码块局部变量现实初始化,即指定初始值。否则不可以访问。
一个类不能有两个同名的成员变量,一个方法也不能有两个同名的方法局部变量。但是两个代码块里面的代码块局部变量可以同名。
如果先定义代码块局部变量,后定义方法局部变量。代码块和方法里面的局部变量也可以同名。
允许局部变量和成员变量同名。此时局部变量覆盖成员变量,如果想访问成员变量,要用this。

成员变量的初始化和内存中的运行机制

类变量和成员变量都在堆中保存。只是不再同一个地方。成员变量属于实例,类变量属于类。

局部变量的初始化和内存中的运行机制

局部变量保存在栈中,不需要垃圾回收,占的内存很小。直到被付初值才会被分配内存

变量的使用规则

成员变量的使用情形

  1. 某个类或者实例的固有信息。如果个个实例都是一样的,用类变量。如果不是一样的,用实例变量。
  2. 保存该类或者实例运行时候的状态信息。
  3. 多个方法都要用到。

6 实现良好的封装

理解封装

通过访问控制符把该隐藏的隐藏起来,该暴露的暴露出来。

使用访问控制符

private 类访问权限
default 包访问权限
protected 子类访问权限
public 公共访问权限

关于访问控制符的使用

  1. 绝大部分成员变量都用private,只有少部分用static,类似全局变量的成员变量用public。除此之外,辅助实现该类的其他方法的工具类也用private。
  2. 如果某个类主要做其他类的父类,则用protected.
  3. 构造器用public。大部分外部类用public。

7 使用package和import

package ,import,import static

  1. 同一个包下的类可以自由访问,但是子包里面的还是必须要写全名
  2. import可以导入包下面的全部类,子包单独import
  3. import static导入静态成员变量,方法

java 常用包

8 构造器的作用和构造器重载

8.1使用构造器执行初始化

在系统执行构造器的执行体之前,系统已经创建了一个对象,只是还不能被外部访问。

9 继承的特点和用法

9.1继承的特点

java是单继承,只能有一个直接父类,但是可以有多个间接父类。
子类是父类的扩展。子类不能获得父类的构造函数。

10 重写父类方法

如果子类对于继承下来的父类的方法不满意,可以重写这个方法。
‘两同两小一大原则’
“两同” 方法名相同,参数列表相同
“两小” 返回值类型要小,抛出的异常要小
“一大” 权限要大
重载和重写:是两个东西。重载是一个类的多个方法,由于形参列表不同所以不同;重写是子类又写了一个和父类对应的方法。

11 super关键字的用法

super用来限定该对象调用父类被覆盖的实例方法。不能够用于static修饰的方法中,因为static是作用于类的。
创建一个子类对象时,系统会给该类中定义的实例变量和父类继承来的实力变量分配内存,即使二者同名。

11.2调用父类构造器

用super可以显式调用父类构造器。必须出现在子类构造器执行体的第一行,因此不能和this同时出现。
当调用子类构造器初始化子类对象,父类构造器一定会在子类构造器之前执行。

12 继承和多态

12.1多态性

java引用变量有两个类型,一个是编译时候的类型,一个是运行时候的类型。编译时候的类型和声明的类型相同,运行时候的类型由实际赋给该变量的对象决定。称为多态。
相同类型的变量,调用同一个方法时呈现出多种不同的行为特征,这就是多态。
成员变量不具有多态性。

12.2 引用变量的强制类型转换

如果想让引用变量调用它运行时的类型的方法,则需要强制类型转换。只能是具有继承关系的两个类型之间。如果是两个没有任何关系的,无法通过编译。如果父类实例转化成子类实例,则这个对象在运行时候必须是子类实例才行,否则会有异常。用instanceof处理。

12.3 instanceof运算符

instanceof运算符前一个是引用变量,后一个是一个类型。用于判断前面的对象是不是后面的类,或者是不是他的子类,或者实现类的实例。如果是,返回true
前面操作数的编译时候的类型要么和后面的类型相同,要么和后面的有父子继承关系(不一定是子类,可以是父类),否则编译有错误。
编译想通过的话,只要有继承关系就行。想返回true,前面的不能是后 面的父类。

13 继承和组合的关系

13.1 使用继承的注意点

  1. 尽量隐藏父类的内部数据
  2. 不要让子类可以随便访问更改父类的方法。辅助方法设置成private;
    如果父类中的方法需要被外部类调用,但是又不想让子类重写这个方法,可以加final;
    如果希望子类重写该方法,但是不希望其他类自由调用,用protected
  3. 父类的构造器里面不要有子类会修改的方法。否则容易出现空指针。
    因为创建子类的对象的时候,一定会先调用父类的构造器,构造器里面调用的方法已经被子类覆盖,所以运行时用的方法是子类的方法。但是子类还没有创建,因此会有空指针的可能性。

什么时候从父类派生子类?

  1. 增加了新的属性
  2. 增加了新的方法

使用组合来实现复用

组合是一种“has”的关系,譬如人有胳膊,腿。
组合和继承的开销一样。
至于怎么用的,书里面写的太少了。没有看明白
先定义private的父类的成员变量,然后在子类的构造器的形参中加入这个成员变量。然后把父类里面所有的public再写一次。(父类子类并不是这样,只是我不知道怎么能够说清楚)

13 构造器和初始化块的作用及区别

13.1 使用初始化块

java类里面可以出现的第四种成员。修饰符只能是static。当创建java对象时,总是先调用该类里面定义的初始化模块,再调用构造函数。

13.2 初始化块和构造器

如果两个构造器里面有相同的代码初始化代码,且这些初始化代码无需接受参数,就可以把它们放在初始化块中定义。

13.3 静态初始化块

如果希望加载类时,对整个类进行某些初始化操作,使用static关键字来修饰初始化模块。叫做类初始化块。

相关文章

网友评论

      本文标题:疯狂java讲义第五章笔记

      本文链接:https://www.haomeiwen.com/subject/uxlfyttx.html