代码块
- 代码块:在Java中,使用{}括起来的代码被称为代码块。
- 代码块的分类:
根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块
局部代码块:
在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块:
在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块:
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。 - 执行顺序:
先执行所有的静态代码块,再执行所有的构造代码块,最后执行构造方法 - 代码块执行特点:
静态代码块只执行一次, 构造代码块和构造方法,每创建一次对象就执行一次
public class Test {
public static void main(String[] args) {
Student student1 = new Student();
System.out.println(student1.num);
System.out.println("---------");
Student student2 = new Student();
System.out.println(student2.num);
System.out.println("---------");
}//静态代码块,随着类的加载而加载,最早执行,而且只执行一次。Student.class 只进一次内存
}
class Student{
int num=50;
static {
System.out.println("类中的静态代码块");
}
public Student() {
System.out.println("空参构造");
}
}
继承思想
-
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可
-
继承格式:
class 子类名 extends 父类名 {} -
继承的注意事项:
- Java语言只支持单继承,不可以多继承
- Java语言支持多层继承
- 子类无法继承父类中的私有的成员变量和方法
- 子类无法继承父类的构造方法,但是可以通过super关键字进行访问
- 如果只需要一个类中的部分功能,不建议继承
-
例:
public class Test { public static void main(String[] args) { System.out.println("B类:"); B b = new B(); System.out.println(b.a); System.out.println("-------"); System.out.println("C类"); C c = new C(); System.out.println(c.a); System.out.println(c.b); } } class A{ int a=10; } class B extends A{ int b=20; } class C extends B{ }
5. 继承的弊端:
让类跟类之间产生了关系,增加了耦合性
6. 软件开发一个原则:高内聚,低耦合
高内聚:一个类独立完成某个功能
耦合:一个类完成功能依赖于其他类
7. `变量访问原则
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show(1);
//变量访问遵循就近原则
//一个方法中要访问的变量,会先在局部找(方法内或形参)如果找到就使用,如果没找到,就去本类的成员位置找,找到就使用
//如果本类成员位置没找到,就去父类成员位置找,找到就使用,最后都找不到,那就报错
}
}
class Fu{
int num=1000;
int b=1;
}
class Zi extends Fu{
int num=10;
int c=20;
public void show(int num){
System.out.println(num); //1
System.out.println(this.num); //10
System.out.println(super.num); //1000
System.out.println("--------------------");
System.out.println(this.c);//20
System.out.println(super.b);//1
}
}
- super关键字:
代表父类空间的标识,通过super 可以访问父类的数据
类似this,但是this代表对本类对象的引用
当我们对子类进行初始化的时候,有时会用到父类中的属性或方法,则需要先对父类进行初始化
public class Test {
public static void main(String[] args) {![在这里插入图片描述](https://img-blog.csdnimg.cn/20190622233209887.)
Zi son = new Zi();
}
}
class Fu{
int num=100;
public Fu() {
super();//调用父类的空参构造
System.out.println("父类的空参构造");
}
}
class Zi extends Fu{
public Zi() { //起始在每个类的构造方法中的第一行,有一条默认语句在调用父类的空参构造 super();
super(); //调用父类的空参构造
System.out.println("子类的空参构造");
}
}
- super和this关键字区别:
1. 调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
2. 调用构造方法
this(…) 调用本类的构造方法
super(…) 调用父类的构造方法
3. 调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法 - 父类子类中代码块执行顺序
public class Test {
public static void main(String[] args) {
//当我们创建子类对象时,父类字节码文件,先加载进内存
Zi zi = new Zi();
}
}
class Fu {
static {
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
System.out.println("构造方法Zi");
}
}
- 方法重写:当子类出现了和父类一模一样的方法(方法名相同,返回值类型相同,参数列表相同)那么就会发生子类方法覆盖父类方法的现象,我们称这种现像叫方法重写
当子类对父类方法实现不满意,或者父类方法不适用时可以使用方法重写
可以使用@Override 检查是否方法重写 - 方法重写注意事项
- 父类中私有方法不能被重写,因为父类私有方法子类根本就无法继承
- 子类重写父类方法时,访问权限不能更低,最好一致
- 父类静态方法,子类也必须通过静态方法进行重写
- 例:
public class Test{
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
Dog dog = new Dog();
dog.eat();
}
}
class Animal{
public void eat(){
System.out.println("吃东西");
}
}
class Cat extends Animal{
@Override
public void eat(){
System.out.println("吃鱼");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("啃骨头");
}
}
- final关键字:
由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
final关键字是最终的意思,可以修饰类,变量,成员方法。 - final修饰特点
修饰类: 被修饰类不能被继承
修饰方法: 被修饰的方法不能被重写
修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量 - 当父类中方法用final修饰时 子类重写会被报错
被final修饰的类不能被继承
被final修饰的变量变成常量 不能再被赋值