参数的传值
在java中,方法的所有参数都是传值的, 也就是说方法中参数变量的值是调用者指定的值的副本
引用类型参数的传值
java的引用型类型包括数组, 对象, 接口. 当参数是引用类型是, 传值传递的是变量中存放的引用, 而不是变量所引用的实体.
总结: 引用类型传递引用, 基本类型传递副本
实例变量和类变量的区别
- 所有对象共享类变量
- 通过类名直接访问类变量
实例方法和类方法的区别
注意: 不能用static修饰构造方法
声明方法时, 在方法类型前面不加关键字static修饰的是实例方法, 加static关键字修饰的是类方法(也称static方法或静态方法)
- 对象调用实例方法
- 当类的字节码文件被加载到内存时, 类的实例变量不会被分配入口地址, 只有当该类创建对象后, 类中的实例方法才分配入口地址, 从而实例方法可以被类创建的任何对象调用, 执行
- 需要注意的是, 当创建第一个对象是, 类中的实例方法就分配了入口地址, 当再创建对象时, 不会为实例方法分配入口地址, 也就是说, 方法的入口地址被所有的对象共享, 当所有的对象不存在时, 方法的入口地址才被取消
- 类名调用类方法
- 对于类中的类方法, 在该类被加载到内存时就分配了相应的入口地址, 从而类方法不仅可以被类创建的任何对象调用, 执行, 也可以直接通过类名调用.
- 类方法的入口地址直接程序退出才被取消, 需要注意的是, 实例方法不能通过类名调用, 只能由对象来调用.
- 和实例方法不同的是, 类方法不可以操作实例变量, 这是因为类创建对象之前实例变量还没有分配内存. 类方法不可以调用类中的实例方法, 只可以调用类中的类方法
方法重载(在cpp那边称函数重载)
在一个类中可以有多个方法具有相同的名字, 但这些方法的参数必须不同, 两个方法的参数不同是指满足下列条件之一
- 参数的个数不同
- 参数的个数相同, 当参数列表中对应的某个参数的类型不同
方法的返回类型和参数的名字不参与比较, 也就是说, 如果两个方法的名字相同, 即使返回类型不同, 也必须保证参数不同. 构造方法也可以重载,** 但构造方法不参与和非构造方法之间的重载比较**
this关键字
this是java中的一个关键字, 表示某个对象, this可以出现在实例方法和构造方法中, 但不可以出现在类方法中.
在构造方法中使用this
当this关键字出现在类的构造方法中时, 代表使用该构造方法所创建的对象.
在实例方法中使用this
实例方法只能通过对象来调用, 不能用类名来调用. 当this关键字出现在实例方法中时, this就代表正在调用该方法的当前对象.
实例方法可以操作类的成员变量, 当实例变量在实例方法中出现时, 默认的格式是: this.成员变量
当static成员变量在实例方法中出现是, 默认的格式是: 类名.成员变量
通常情况下可以省略实例变量名字前面的”this”, 以及static变量前面的”类名”.
除非当实例或static成员变量的名字和局部变量的名字相同时, 成员变量前面的”this”或”类名”不可以省略
访问权限
限制修饰符private, protected和public用来修饰成员变量(不可以修饰局部变量)或方法(包括构造函数)
子类与继承
子类和父类在同一包中的继承性
如果子类和父类在同一个包中, 那么子类自然地继承了其父类中不是private的成员变量作为自己的成员变量, 而且也自然地继承了父类中不是private的方法作为自己的方法, 继承的成员变量或方法的访问权限保持不变.
子类和父类不在同一个包中的继承性
当子类和父类不在同一个包中时, 父类中的private和友好访问权限的成员变量不会被给予子类继承, 也就是说, 子类只继承父类中的protected和public访问权限的成员变量作为子类的成员变量; 同样只继承父类中的protected和public访问权限的方法作为子类的方法
子类对象的特点
当用子类的构造方法创建一个子类的对象时, 不仅子类中声明的成员变量被分配了内存空间, 而且父类的成员变量也都分配了内存空间, 但只能将其中一部分(即子类继承的那部分成员变量)作为分配给子类对象的变量. 也就是说, 父类中的private成员变量尽管分配了内存空间, 也不作为子类对象的变量, 即子类不继承父类的私有成员变量, 同样, 如果子类和父类不在同一个包中, 尽管父类的友好变量分配了内存空间, 但也不作为子类对象的变量, 即如果子类和父类不在用一个包中, 子类不继承父类的友好成员变量
成员变量的隐藏
当所声明的成员变量的名字和从父类继承来的成员的名字相同(声明的类型可以不同), 在这种情况下子类就好隐藏所继承的成员变量.
子类隐藏继承的成员变量的特点如下
- 子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员变量
- 子类对象仍然可以调用从父类继承的方法操作被子类隐藏的成员变量, 也就是说, 子类继承的方法所操作的成员变量一定是被子类继承或隐藏的成员变量
方法重写
子类中定义一个方法, 这个方法的类型和父类的方法的类型一致或者是父类的方法的类型是子类型(所谓子类型, 是指如果父类的方法的类型是”类”, 那么允许子类的重写方法的类型是”子类”), 并且这个方法的名字, 参数个数, 参数的类型和父类的方法完全相同.
注意: final方法无法重写
在重写父类的方法时, 不允许降低方法的访问权限, 但可以提高访问权限(访问限制修饰符按访问权限从高到低的排列顺序是public->protected->友好类->private)
super关键字
用super操作呗隐藏的成员变量和方法(public跟protected类型的)
使用super调用父类的构造方法
当用子类的构造方法创建一个子类的对象时, 子类的构造方法总是先调用父类的某个构造方法. 也就是所, 如果子类的构造方法没有明显地指明父类的哪个构造方法, 子类就调用父类的不带参数的构造方法
由于子类不继承父类的构造方法, 所以子类在其构造方法中需使用super来调用父类的构造方法, 而且super必须是子类构造方法中的头一个语句, 即如果在子类的构造方法中没有显示地写出super关键字来调用父类的某个构造方法, 那么默认的有:
1 | super() |
如果在子类的构造方法中显示地写出了super关键字来调用父类的某个构造方法, 那么编译器不再提供默认的super语句.
find类, final方法与常量
- 可以使用final将类声明为final类. final类不能被继承, 即不能有子类.
- 如果用final修饰父类中的一个方法, 那么这个方法不允许子类重写, 也就是说, 不允许子类隐藏可以继承的final方法(老老实实地继承, 不许做任何篡改)
- 如果成员变量或局部变量被修饰为final, 那么它就是常量. 由于常量在运行期间不允许在发生变化, 所以常量咋声明是没有默认值, 这就要求程序在声明常量是必须指定该常量的值
对象的上转型对象
对象的上转型对象的实体是子类负责创建的, 但上转型对象会失去原对象的一些属性和功能(上转型对象相当于子类对象的一个”简化”对象)
- 上转型对象不能访问子类新增的成员变量(失去了这部分属性), 不能调用子类新增的方法(失掉了一些行为)
- 上转型对象可以访问子类继承或隐藏的成员变量, 也可以调用子类继承的方法或子类重写的实例方法
- 上转型对象操作子类继承的方法或子类重写的实例方法, 其作用等价与子类对象去调用这些方法
注意: 如果子类重写了父类的静态方法, 那么子类对象的上转型对象不能调用子类重写的静态方法, 只能调用父类的静态方法
abstra类和abstract方法
- 用关键字abstract修饰的类称为abstract类(抽象类)
- 用关键字abstract修饰的方法称为abstract方法(抽象方法)
对于abstract方法, 只允许声明, 不允许实现(没有方法体), 而且不允许使用final和abstract同时修饰一个方法或类, 也不允许使用static和private修饰abstract方法, 即abstract方法必须是非private的实例方法(访问权限必须高于private)
abstract类可以有abstract方法和非abstract方法(普通方法)
abstract类中也可以没有abstract方法
对于abstract类, 不能使用new标识符创建该类的对象. 如歌一个非抽象类是某个抽象类的子类, 那么它必须重写父类的抽象方法, 给出方法体
如果一个非abstract是abstract类的子类, 那么它必须重写父类的abstract方法, 即去掉abstract方法的abstract修饰, 给出方法体, 如果abstract类是abstract类的子类, 那么它可以重写父类的abstract方法, 可以继承父类的abstract方法.
可以使用abstract类声明对象, 尽管不能使用new标识符创建该对象, 但该对象可以成为子类的上转型对象, 那么该对象就可u调用子类重写的方法.
接口
接口无法调用类中的其他非接口方法
接口本身默认是abstract的, 可以是public的, 也可以是friendly的,其他不行
接口里的方法默认是abstract的, public的,其他的不行