一.代码块
1.什么是代码块?
一对{ }
2.代码块的分类以及特点
1.局部代码块
局部代码块定义在方法中,用大括号{ }包含。例如在method()方法中创建一个局部代码块
public void method() {
{
int x = 18;
System.out.println("age = " + x);
System.out.println("这是一个局部代码块");
}
}
在上述代码中,我们可以直接去掉代码块的大括号,运行效果和加代码块一致。那么,有什么必要使用局部代码块吗?
局部代码块可以限制变量的生命周期(作用域的问题),也就是说在代码块中创建的变量只在代码块中有效,当代码块运行结束,变量就会被释放,从而节省内存空间。
2.构造代码块
构造代码块定义在类中 方法外用大{ }表示
class Teather{
String name;
{
//构造代码块
}
public void introduce(){
System.out.println("我的名字" + name);
}
}
class Demo{
public static void main(String[] args) {
Test test = new Test();
System.out.println("-------------");
Test test2 = new Test(1);
}
}
public class Test {
public Test() {
System.out.println("无参构造");
}
public Test(int num) {
System.out.println("带参构造");
}
{
System.out.println("构造代码块");
}
}
结果
构造代码块
无参构造
-------------
构造代码块
带参构造
可以看出:无论是使用无参构造还是有参构造来创建对象,首先都会执行构造代码块中的内容。所以它可以对对象进行初始化,在对象创建时,就会实现该功能,调用构造代码块,从而减少代码的冗余度,提高代码复用性。
调用顺序: 在你创建对象的时候,如果你有构造代码块 系统会帮你先调用构造代码块 再调用构造方法
作用:如果有相同的方法要去执行 可以在构造代码块中去调用
3.静态代码块
静态代码块同样是定义在类中的,相对于构造代码块,只是在大括号前加了一个static修饰符。同样的,我们通过代码来看一下它的作用
class Demo01{
public static void main(String[] args) {
StaticTest st = new StaticTest();
System.out.println("----------------");
StaticTest st2 = new StaticTest(1);
}
}
public class StaticTest {
public StaticTest() {
System.out.println("无参构造");
}
public StaticTest(int num) {
System.out.println("带参构造");
}
static {
System.out.println("静态代码块");
}
}
结果
静态代码块
无参构造
----------------
带参构造
可以看到,我们以无参和带参的形式创建对象,虽然同构造代码块一样,执行在构造方法前面,但是静态代码块仅执行一次。
静态代码块是在类加载时初始化的,只加载一次,随着类的加载而加载;所以有些代码必须在项目启动的时候就执行的话,需要使用静态代码块。
作用:加载驱动(JDBC数据库的连接)
4.优先级顺序
public class YouXianJi {
public YouXianJi() {
System.out.println("无参构造");
}
public YouXianJi(int x) {
System.out.println("带参构造");
}
{
System.out.println("构造代码块");
}
static {
System.out.println("静态代码块");
}
// 成员方法
void method() {
{
System.out.println("局部代码块");
}
}
public static void main(String[] args) {
System.out.println("main()方法");
YouXianJi yxJ = new YouXianJi(); // 无参方式创建对象
yxJ.method();
System.out.println("---------------------------------------");
YouXianJi yxji = new YouXianJi(1); // 带参方式创建对象
yxji.method();
}
}
结果
[静态代码块
main()方法
构造代码块
无参构造
局部代码块
---------------------------------------
构造代码块
带参构造
局部代码块]
所以可以看出来优先执行顺序是静态代码块 > main()方法 > 构造代码块 > 构造方法。
二.类的继承
对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础。抽象、封装、继承、多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点
继承是所有OOP语言不可缺少的部分,在java中使用extends关键字来表示继承关系。当创建一个类时,总是在继承,如果没有明确指出要继承的类,就总是隐式地从根类Object进行继承。比如下面这段代码:
实现代码:
class Demo{
public static void main(String[] args){
Man m = new Man;
m.name = "小李子";
m.age = 12;
m.introduce();
}
}
class Person {
String name;
int age;
public Person() {
}
public void introduce(){
System.out.println(name + "---" + age);
}
}
1.在类Man继承于Person类,这样一来的话,Person类称为父类,Man类称为子类,如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量。在java中,只允许单继承,不允许多继承,但是可以使用接口来实现,java中只允许多层继承(属性和方法会传递继承)也就是爷爷类 爸爸类 儿子类
class Grandfather{
}
class Father extends Grandfather{
}
class Son extends Father{
}
儿子 继承 爸爸 继承 爷爷 具有传递性
如果一个类没有写继承的类 实际上是继承的系统的 Object类 ,Object类 是java中最顶端的类(基类)
比如说:
如果我想得到类中 共有的方法和属性 使用哪个类?
使用继承链最顶端的类
如果我想得到类中 特有的方法和属性 使用哪个类?
使用最末端的类
2.构造方法(构造器)
子类是不能够继承父类的构造方法的,但是要注意的是,如果父类的构造方法都是带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造
// 形状类
class Shape {
String name;
public Shape(){ // 无参构造方法
name = "shape";
}
public Shape(String name) { // 有参构造方法
this.name = name;
}
}
class Circle extends Shape { // 圆形类继承形状类
private double radius; // 半径
public Circle() {
// 如果你没有调用父类的构造方法
// 那么系统会在这里帮你调用一下父类无参构造方法
radius = 0;
}
public Circle(double radius) {
// 不管你是有参无参构造方法
// 只有你没有调用父类的无参构造方法 系统都会帮你调用
// 保证继承的完整性
super();
this.radius = radius;
}
}
4.super
super主要有两种用法:
1)super.成员变量/super.成员方法;
2)super( );// 调用父类的构造方法
第一种用法主要用来在子类中调用父类的成员变量或者方法, super点属性(方法) : 可以调用到父类的属性(方法);第二种主要用在子类的构造方法中显示地调用父类的构造方法,要注意的是,如果是用在子类构造方法中,则必须是子类构造方法的第一个语句, super() :调用父类的构造方法
其实这个super和this关键字还是很相似的
5.this和super的区别
1.this 在类中代表本类的对象(当前类的对象)
2.super 在类中代表的是 父类的对象
this点属性 : 可以调用当前类的属性
(如果你现在当前类找这个属性 没找到的话 会去父类里去找) 遵循了就近原则
super点属性 : 可以调用到父类的属性
this() : 调用本类的构造方法
super() :调用父类的构造方法
6.两个类的继承
父类 没有 无参构造方法 (有 有参的构造方法)
子类的构造方法如何去写? 可以指定调用有参的构造方法
实现代码:
public class Test {
public static void main(String[] args){
DaZhong daZhong = new DaZhong();
daZhong.sayHi();
System.out.println("-------");
DaZhong daZhong2 = new DaZhong("奥迪");
daZhong2.sayHi();
}
}
// 我也不知道什么类
class Cor{
String name;
String color;
// 无参构造方法
// public Cor() {
// System.out.println("Car 我是无参构造方法");
// }
public Cor(String name) {
this.name = name;
System.out.println("我是Car 的有参构造方法");
}
}
// 大众类
class DaZhong extends Cor{
public DaZhong() {
super("我很普通");
System.out.println("Da 我是无参构造方法");
}
public DaZhong(String name) {
super(name);
this.name = name;
}
public void sayHi() {
System.out.println(name + "--" + color);
}
}
7.继承 父类和子类有相同 成员方法
实现代码:
class Person{
public void print(){
System.out.println("我会画画");
}
}
class Student{
// 注解 @Override 标识着这个方法是重写父类的方法
@Override
public void print() {
super.print;// 这里调不调用父类方法 要根据实际开发来写
System.out.print("我不仅会画画,也会涂鸦");
}
}
父类和子类方法名完全一致时 叫做 方法重写
这时super点方法 可以调用父类的方法
重写的应用场景:
当子类的方法 相当于父类的方法 相对 父类方法有升级
这时你可以使用 方法的重写
Override和Overload有什么区别?
方法重载是方法名相同但是参数不一样
Override 重写
Overload 重载
三.final 关键字
final从字面上理解含义为“最后的,最终的”(绝育)。在Java中也同样表示出此种含义。
final可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
1.final修饰变量
final 修饰的变量 相当于常量 (不能被修改的量)
命名规则 名字全部大写 多单词时下划线分开
public static final double MA_VALUE = 3.14;
2.final修饰类:
final修饰类即表示此类已经是“最后的、最终的”含义。因此,用final修饰的类不能被继承,即不能拥有自己的子类。
如果试图对一个已经用final修饰的类进行继承,在编译期间或发生错误。
public final class A {
}
// 编译错误!A是final类型,不可被继承!
public class B extends A{
}
3.final修饰方法:
final修饰的方法表示此方法已经是“最后的、最终的”含义,亦即此方法不能被重写
public class A {
// final方法f
public final void f() {
System.out.println("类A中的final方法f被调用了");
}
}
public class B extends A {
// 编译错误!父类的f方法是final类型,不可重写!
public void f() {
System.out.println("类B中的方法f被调用了");
}
}