本帖最后由 小石姐姐 于 2017-12-22 16:26 编辑
JavaSE进阶课程笔记 static静态关键字
static:是一个关键字,用来修饰成员变量()和成员方法(定义类的时候修饰方法)
调用
类名.静态成员属性:System.out
类名.静态成员方法():Arrays.toString(arr)
静态的特点:
被该类所有的对象所共享
可以直接使用类名来调用
静态所修饰的成员加载优先于对象
静态资源在创建类时加载并初始化(在方法区中)
非静态资源在创建对象时才加载并初始化(在堆内存中)
静态成员的生命周期
随着类的加载而加载,直到程序结束
静态成员和非静态成员的区别
生命周期不同
静态成员:随着类的加载而创建,随着程序的结束而销毁
非静态成员:随着对象的创建而创建,随着对象的销毁而销毁
所以, 静态成员的生命周期优先于非静态成员创建, 晚于非静态成员销毁
内存中的定义位置不同
静态成员:方法区中类字节码区域的静态区中
非静态成员:堆内存中
初始化实时机不同
静态成员:类加载时初始化
非静态成员:对象创建时初始化
注意事项;
静态方法:
可以调用静态的成员变量
可以调用静态的成员方法
不可以调用非静态的成员变量和成员方法
非静态的方法:
可以调用静态的成员变量和成员方法
可以调用非静态的成员变量和成员方法
综上所述:
静态方法中只能调用静态成员:
原因: 因为静态方法随着类的加载而加载, 而非静态方法随着对象的创建而加载,
当静态方法加载时, 并不一定创建了对象, 所以不一定有对象可以调用非静态方法,
为了避免这种不安全的访问, 所以静态方法中只能调用静态资源
非静态方法中可以调用静态和非静态成员
原因: 非静态方法随着对象的创建而创建, 对象创建的前提是类已经加载,
类在加载时已经加载了静态资源, 所以当对象调用非静态方法时, 静态资源一定存在, 这种访问是安全的
静态方法中**不能**用this
因为this引用当前类的对象, 而静态方法在类加载时已经加载, 此时没有对象可以引用
static的优点:
为共享数据提供同一个存储空间,节省内存空间
可以直接类名调用,不用创建对象
缺点:
访问有局限性,只能访问静态
应用场景:
作为该类所有对象共享的数据
工具类
创建一个类
把构造方法私有
所有方法用static修饰, 类名直接调用
Math类
静态成员属性:
static double PI : 获取圆周率
静态成员方法:
static int/long/float/double abs(int/long/float/double a):返回一个数字的绝对值
static double ceil(double a):向上取整
static double floor(double a) 向下取整
static long round(double a) 四舍五入
static int round(float a)`: 四舍五入取整
static int/long/float/double max(int/long/float/double a, int/long/float/double b)`: 返回两者较大值
static int/long/float/double min(int/long/float/double a, int/long/float/double b)`: 返回两者较小值
static double pow(double a,double b) 计算第一个数的第二个数次幂
static double random() 生成[0.0, 1.0)的随机小数
代码块 : 在Java中,使用{}括起来的代码被称为代码块
分类:
局部代码块:
定义位置: 方法中
执行时机: 执行到方法中的局部代码块时
作用: 控制局部变量的生命周期(作用域)
构造代码块:
定义位置: 类中, 方法外
执行时机: 创建一个对象时, **在构造方法之前执行**, 无论使用无参还是有参构造方法
作用: 为所有构造方法都执行同一种操作, 减少构造方法中编写重复代码
静态代码块:
定义位置: 类中,方法外,static修饰
执行时机:加载类时执行,只执行一次
作用:加载类时进行一些初始化操作,并且只需要执行一次
同步代码块: 多线程讲解
继承
概念/;
从已有类派生出新的类
已有类称父类(基类),新类称为子类(派生类)
子类对于父类的关系就是继承
作用:
多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),再让多个类去继承这个父类,我们的多个类就可以获取到父类的成员了.
继承使用关键字:extends
作用: 子类继承父类时使用
定义位置: 子类类名后
格式: 权限修饰符 class 子类类名 extends 父类类名 {}
继承的特点:
Java语言只支持单一继承,只能继承一个父类
Java语言支持多层继承
不支持多继承: 有些语言如C++支持一个类同时继承多个直接父类, 但Java不支持
继承中成员变量的特点:
子类只能获取父类非私有成员
子父类中的成员变量名字不一样直接获取父类的成员变量
就近原则:谁离我近我就用谁
如果有局部变量就是用局部变量
如果没有局部变量,有子类的成员变量就使用子类的成员变量
没有局部变量和子类的成员变量,使用父类的成员变量
没有局部变量, 本类成员变量和父类成员变量, 则报错
super:可以获取父类的成员变量和成员方法,用法和this相似
super.name
this:获取本类的成员变量
this.name
继承中成员方法的特点:
子类中没有这个方法,调用父类的
子类中重写了这个方法,调用子类的
方法重写:在子父类中,子类的方法和父类的完全一样,子类重写父类的方法,当子类重写了父类的方法之后,使用子类对象调用的就是子类方法
方法重载:在一个类中,有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关
方法重写的应用场景:
当父类的方法不能满足子类使用,这个时候子类重写父类的方法,
并且可以在方法中使用关键字super调用父类的方法,这样做既可以保有父类的功能,也可以拥有子类持有的功能
方法重写的注意事项:
不能重写父类私有的方法
权限必须大于等于父类方法的权限
重写的特点:
* 子类对象调用一个方法时:
* 子类中重写了这个方法, 则调用子类的重写方法
* 子类中没有这个方法, 则调用父类的
* 父类如果没有, 报错
注解 :@Override
用于约束被注解的方法必须是重写父类的方法, 如果父类没有这个方法则报错
继承中构造方法的执行顺序:
1.在有子父类继承关系的类中,创建子类的对象,调用子类的构造方法,
如果子类构造方法的第一行代码没有调用父类的构造方法,则会默认的调用父类的无参构造
2.肯定会先执行父类的构造,因为要先给父类的成员变量初始化,然后再去执行子类构造中的其他代码
this和super的区别:
this:
对当前对象的引用
调用子类的成员变量: this.age;
调用子类的成员方法: this.eat();
在子类的构造方法第一行调用子类其他构造方法: this();
当子类没有父类的某个成员变量或成员方法时,
this也可以调用父类的成员变量或成员方法(因为子类继承了父类的成员)
super:
子类对象的父类引用
调用父类的成员变量 super.age;
调用父类的成员方法 super.eat();
在子类的构造方法第一行调用父类的构造方法 super();
继承的优缺点:
优点:提高代码的复用性
提高代码的可维护性
缺点:类的耦合性增强了
开发原则:高内聚低耦合
内聚:就是自己完成某件事的能力
耦合:类与类的关系.耦合高了是类与类之间相互依赖太多
匿名对象:没有名字的对象,没有变量引用的对象
匿名对象的格式:
调用属性:new 类名().属性;
调用方法:new 类名().方法();
作为参数:Student.eat(new Food("苹果"));
匿名对象的应用场景:
当方法只调用一次的时候可以使用匿名对象
作为参数传递
注意:匿名对象可以调用成员变量并赋值,但是赋值并没有意义
final关键字:
修饰符,可以用于修饰类,成员方法和成员变量
final所修饰的类:
不能被继承,不能有子类
final所修饰的方法:
不能被重写
final所修饰的变量: 自定义变量
是不可以修改的,是常量
* 基本数据类型: 其值永不改变的常量
* 引用数据类型: 引用一经初始化便不能修改, 且必须在使用前对其初始化
* 常量名命名规则: 字母全都大写, 不同单词用下划线分隔, 如`YOUR_AGE
抽象类:
* 什么是抽象: 无法具体描述的, 但是能够表达出共性
* 关键字: abstract, 能够修饰类, 方法
* 作用:
* 抽象类
* 使用abstract修饰的类
* 含有抽象方法的类必须定义为抽象类;
* 抽象方法
* 没有方法体的方法: `修饰符 abstract 方法名();`
* 抽象方法必须被子类重写
* 抽象类和类的关系
* 抽象类也是类
* 一个类继承了抽象类后只有2种选择:
* 重写父类的抽象方法
* 将该类本身修改为抽象类
* 抽象类的特点:
* 抽象类和抽象方法必须用abstract修饰
* 抽象方法只能定义在抽象类中
* 抽象类中并不一定需要抽象方法, 抽象类中也可以有非抽象的方法
* 抽象类不能创建对象, 但是可以有构造方法(对成员进行初始化)
* 抽象类和类之间也存在继承关系
* 一个类继承了抽象类后只有2种选择:
* 重写父类的抽象方法
* 将该类本身修改为抽象类
* 抽象类成员的特点:
* 成员变量:
* 可以有成员变量
* 可以有常量
* 成员方法:
* 可以有抽象方法
* 可以有非抽象的方法
* 构造方法
* 可以有, 通过子类调用super()来实现抽象类成员的初始化
* abstract不能与final和private一起用
* final: 因为抽象方法必须被重写, 而final修饰的方法不能被重写, 有冲突
* private: 因为抽象方法必须被重写, 而private方法子类看不见, 所有有冲突
* 抽象思想的作用: 起到规范的作用
不创建对象的方式:抽象类 2:构造方法私有
//抽象类不能创建对象,则找类中的返回自身类型的静态方法(直接类名调用方法),再用该类接收,就相当于创建了该类对象
例如:Calendar c = Calendar.getInstance();// Calendar类 中的方法getInstance()方法,返回的是Calendar类
接口:接口是一个比抽象类还抽象的类,接口里所有的方法都是抽象方法
接口和类的关系是实现 implements
格式:权限修饰符 class 类名 implements 接口名1,接口名2{}
格式:
权限修饰符 interface 接口名 {
}
接口的成员特点:
只能有抽象方法
只能有常量
默认使用public& abstract修饰方法
只能使用public& abstract修饰方法
默认使用public static final 修饰常量
建议:手动的给上默认修饰符
注意:接口不能创建对象(不能实例化)
类与接口的关系是实现关系,一个类实现一个接口必须实现它所有的方法
接口和类之间的各种关系:
类与类:继承关系,单一继承,多层继承
类与接口:实现关系,多实现
接口与接口:继承关系,多继承,多层继承
接口的优点:
打破了继承的局限性;
对外提供规则;
降低了程序的耦合性;(可以实现模块开发,定义好规则,每个人实现自己的模块,提高了开发效率)
接口和抽象类的区别:
共性: 不断的抽取出抽象的概念
区别1:与类的关系
类与接口是实现关系,而且是多实现,一个类可以实现多个接口
类与抽象类是继承关系,Java中的继承是单一继承,一个类只能有一个父类,Java中的继承是多层继承
区别2: 成员
成员变量:
抽象类可以有成员变量,也可以有常量
接口只能有常量
成员方法:
抽象类可以有抽象方法,也可以有非抽象方法
接口只能有抽象方法,而且方法有默认修饰符 public abstract
构造方法:
抽象类有构造方法
接口没有构造方法
分析题:
由下至上 不断向上抽取的过程
实现:
由上至下 先实现共性
使用:
使用具体的子类
多态
多态的前提:
子父类的继承关系
方法的重写
父类或父接口引用指向子类对象
动态绑定:运行期间调用的方法,是根据其具体的类型
多态的成员特点:
成员变量:编译时看的是左边的引用类型,运行时看的也是左边,变量没有重写的概念
成员方法:编译时看的是左边的引用类型,运行时看的右边,看的具体的对象
静态方法:编译时看的是左边的引用类型,运行时看的也是左边
编译时看的都是左边,因为当时还没有对象,运行成员方法是看的是右边,其他看的都是左边
多态优缺点:
缺点:无法直接访问子类特有成员
优点:可以提高可维护性(多态前提所保证的),提高了代码的可扩展性
* 向上转型
* 子类型转换为父类型(自动转换)
* 向下转型
* 父类型转换为子类型(强制转换)
* 转型时的注意事项:
* 只有子父类存在继承关系时, 才能自动向上转型
* 只有子类对象本身就是要被强转的目标类型时, 才能够强转. 否则会抛出类型转换异常
* 可以使用instanceof语句来判断对象的实际类型
* 格式: `对象的变量名 instanceof 类名`
* 解释: 如果是该类型则返回true, 如果不是则返回false
|
|