java之类

类是引用类型。

类的修饰符有public,final,abstract。

类中包括,成员变量(field)可以由public,protected,private中任意一个修饰,static,final可以组合修饰。

类中包括,成员方法,可以由public,protected,private中一个修饰,abstract和final其中一个修饰,static组合修饰。

其中static是静态,是类所有的,是所有类的对象所共有的部分,不属于任何一个对象。调用方法为类名.xxx。静态成员不能直接访问非静态成员。

对于成员变量,一般命名小写,private修饰。然后添加public的setXxxx和getXxx方法。

类中包括,构造器。修饰符为public,protected,private中其一。没有返回值,和类名一模一样。

对象名存储在栈中,是对象的引用,也就是指针变量。对象存储在堆中。当将对象名赋值为null后,则对象失去引用,将被垃圾回收。

类中的this,表示了当前对象。一般可以省略。静态方法不可以使用this。成员方法中调用类的其他成员时,默认添加this.。
当成员方法中存在于成员变量同名的局部变量时,此时成员变量需要加this。

当类的成员方法返回this时,此时该方法可以多次连续调用。

方法不能独立定义,必须定义在类里。

方法只能属于类或类的对象。

不能直接执行方法,类中的直接调用,是省略了this.或者类.。

java中的参数传递,只有值传递。对于引用类型的参数,同样是传递指针变量的值,即复制了一个变量名,至于变量名所引用的对象,则还是堆里的唯一一份。所以值类型和引用类型都是值传递,导致不同结果的本质原因还是值类型和引用类型的区别。

可以定义形参个数可变的函数。但是只能放在最后,也就是只能存在一个。其本质就是一个数组,所以调用此类方法,既可以传入多个类型相同的变量,也可以传入一个数组。

1 public static void test(int a,String ... books){
2 for(var x:books){
3 System.out.println(x);
4 }
5 }
View Code

递归方法是指调用自身的方法。。递归一定要向已知方向调用。

方法重载,函数名相同,参数不同。

 

类的生命周期:类加载、类验证、类准备、类解析、类初始化。

成员变量包括类成员变量即static,和实例成员变量。

类成员变量的作用域是从类准备到类销毁,与类共存。

实例成员变量的作用域是从实例存在到结束。与实例共存。

成员变量可以不进行初始化。由类的构造函数进行初始化。没有构造函数,java提供默认构造函数。初始化与数组的默认初始化相同。

局部变量分为形参,不用初始化,作用域为方法开始到方法结束。方法局部变量,定义在方法中,作用域为定义开始到方法结束,必须初始化。代码块局部变量 ,作用域为定义开始到代码块结束,必须指定作用域。

局部变量可以与成员变量名字相同,这时,局部变量将覆盖成员变量。如果要访问成员变量,则需要this.或者类.。

当系统第一次使用某个类时,会加载·这个类,准备阶段,会为该类的类变量分配空间并指定初始值。

局部变量定以后,系统并不会为之分配内存空间,只有在初始化后,系统才分配。对于基本类型的局部变量,直接压入所在方法的栈中,对于引用类型的局部变量,则将变量值压入栈,通过变量值(地址)引用到该变量实际的引用对象或者数组。

因此局部变量不需要垃圾回收。随着方法或者代码块的结束而结束。

局部变量的作用域越小越好,提高程序的内聚性和节省内存

如果一个java源文件里没有public类,则java源文件可以任何名字。如果有public类,则只能为此类的名字。

封装的目的是为了隐藏实细节,暴露访问方法。从而可以保护成员变量不被非法操作,可以对数据进行检查。提高了代码的可维护性。

需要将对象的成员变量和实现细节隐藏起来,不允许外部直接访问。

把方法暴露出来。

private:只有类内部可以访问。

default:包内可以访问。

protected:包内访问,不同包的子类访问。

public:公开访问。

经成员变量定义为私有,并且通过各自对应的setter和geter方法操作和访问他们,gettee和setter合起来就变成了属性,如果所有属性都这么做,那么这个类就是符合javaBean的规范类。

只有getter方法为只读属性

高内聚:尽可能把模块内部数据、功能实现细节隐藏在模块内部独立完成,不允许外部直接干预。

低耦合:仅暴露少量的方法给外部使用。

 包的概念

package,写在源代码第一行非注释行。表示此源代码定义的所有类都输入这个包。

javac -d. xxx.java 会将xxx类生成的.class文件在此类所在的包文件夹下。

当虚拟机加载.class文件时,会搜索classpath环境变量指定目录,在这些目录中找对应层次的包区查找.class文件。

同一个包的不同类,不一定放在同样的目录下,只要classpath包含两个路径,则虚拟机会根据classpath找到两个路径,并把它们当成同一个包下的类来处理。

java源文件,也必须有与包层次相同的文件路径存放,并且与.class文件分开存放。

访问其他包的成员,必须加上包名.xxx,即使是同一个包中另外的一个子包也必须加上完整的包层次。

为了简化,采用了import方法,

import package.subpackage...ClassName;

引入包中的某个类

import package.subpackage...*;

引入包中的所有类。

import static package.subpackage...classname.fieldName|methodname;

引入包中的静态成员

import static package,subpackage...classname*

引入类中所有静态成员变量和方法。

构造器

用来初始化类的实例。

系统有默认无参构造器,为了初始化为其他值,使用自己定义的构造器。

构造器被调用时,系统会先为该对象分配内存空间,并为这个兑现执行默认的初始化,此时对象已经产生,在构造器执行之前已经产生对象,只是这个对象只能供构造器this引用。构造器执行完之后,返回这个对象,赋给一个引用类型的变量。

构造器重载

当定义了有参数的构造器之后,系统默认的无参构造器不起作用了。

这是如果重载构造器,自己再定义个无参的,就可以使用了。

还可以定义多个构造器。’

如果构造器之间,有相同的参数,则用this调用参数少的构造器。保证代码的唯一,减少冗余。

类的继承

java的继承为单继承,即每个子类只有一个直接父类。

继承使用extends关键字

子类只能从父类中获得成员变量、方法和内部类(包括内部接口、枚举),不包括构造器和初始化块。

定义一个类时,若为指定其直接父类,则默认这个类扩展java.lang.Object类。

子类扩展了父类,子类是特殊的父类。

重写

两同两小一大

子类方法与父类方法,方法名和参数列表都相同。如果参数列表不同则是子类重载父类方法。

两小:子类的方法返回值类型应该比父类的更小或者相等;子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等。

一大:子类方法的访问权限应比父类方法的访问权限更大或者相等。

覆盖方法和被覆盖方法,要不都是类方法要不都是实例方法。

子类覆盖了父类的方法后,子类对象将无法调用父类的方法。但可以在子类方法中饭访问父类被覆盖的方法。如果被覆盖的是类方法,则用类名,如果是实例方法,则用super.。

如果父类方法是private,则子类无法重写。即使有参数名,返回值,函数名一样的函数,只是重新声明了一个而已。

super不能出现在static修饰的方法中。

如果子类的实例变量与父类的实例变量相同,则子类隐藏父类的实例变量。如果要调用父类的实例变量,需要super.。

如果子类隐藏父类的那个变量是私有,而父类是公有,则将子类对象强制转换为父类以后可以调用父类的对象。

子类隐藏父类实例变量以后,初始化子类对象,将会创建两个对象(一个父类,一个子类)。

子类调用父类构造器

1.子类构造器执行体的第一行显示super调用父类构造器,系统根据传入的实参,调用父类的构造器。必须是第一行,因此super和this不能同时存在。

2.子类构造器使用this调用本类中重载的构造器,调用这个构造器之前,会先调用父类构造器。

3,子类构造器既没有super也没有 this,系统将会在执行子类构造器时,先调用父类的默认无参数构造器。

多态

java的引用变量有两个类型,一个是编译时类型,一个是运行时类型。编译时类型由声明变量是使用的类型决定,运行时类型由实际赋值给变量的对象的类型决定。如果编译时类型和运行时类型不一致时,就可能出现所谓的多态。

当引用变量,编译时时类型A,运行时时子类B,此时将会出现同样是类型A,当调用同一个方法时,出现不同的状态。这时就出现了多态。

当然若这个对象调用A中不存在的方法,则会出现错误。因为java的引用变量,在编译阶段,只会调用其编译时所具有的方法,而运行时阶段,才会调用其运行时阶段具有的方法。因此编写代码时,只能调用声明该变量时的类型所具有的方法。

对于变量,只能访问他编译时类型所拥有的变量,而不能访问其运行时所拥有的变量。

强制类型转换

instanceof操作符,在进行强制类型转换之前,首先判断前一个对象是否是后一个类型的实例,若是,则能强转成功。使得代码更强壮。

instanceof,使用时,前面的实例的编译时类型,必须与后面的类型具有父子关系,若没有则报错。

值类型的强制转换,只能在数值类型直接进行。整数,字符和浮点。不能喝布尔

引用类型的强制转换,只能在有父子关系的两个类型之间转换。如果试图把父类型转换为子类型,则这个对象必须实际上是子类型才可以。即编译时是父对象,运行时时子类型。

强转之前,最好判断instanceof

继承与组合

继承实现了类的重用,但是继承破坏了封装。

为了保证良好的封装性:

1.尽量隐藏父类的内部变量。声明为私有

2.不要让子类可以随意访问、修改父类方法。将父类工具方法声明为私有,需要被外界调用但不希望被子类重写的方法是用final.

3.尽量不要在父类构造器中调用将要被子类重写的方法。

当子类需要额外的变量,或者需要新的行为时才声明子类。

组合

把旧类对象作为新类的成员变量组合进来,用来实现新类的功能。用户看到的是新类的方法,而不能看到被组合对象的方法。因此在新类里需要使用private修饰被组合的旧类对象

继承要表达的是“is-a”的关系,组合表达的是“has-a”的关系

 初始化块

初始化块是java类里可以出现的第四中成员。

初始化块分为实例初始化块和类初始化块(static)

 实例初始化块:在创建实例时,总是先调用实例初始化块,会一级一级往上找,然后调用初始化块。之后再执行构造器。

类初始化:

首先静态初始化块中不允许有实例成员。

类初始化块是类相关的,系统旨在类初始化阶段段执行类初始化块。因此类初始化块要先于实例初始化块执行。并且只在类初始化时执行一次。再次声明类时,不执行。

posted @ 2020-02-17 13:00  小甲点点  阅读(121)  评论(0编辑  收藏  举报