一 代码块
1.局部代码块(方法)
书写位置:方法中
作用:限制作用域
书写位置:类中 方法外
代码的执行顺序:
①系统调用
②只要创建对象 就会调用
③构造代码块 在 构造方法 之前被调用
作用:当你有方法 需要每一个对象都调用的时候,可以将这个方法在构造代码块中调用(不常用)
3.静态代码块使用关键词static修饰的代码块
位置:类中方法外
调用顺序:
1.随着类的加载
2.只加载一次
3.在构造代码块之前执行
应用场景:
加载驱动(加载数据库驱动---一个类)
4.同步代码块(多线程部分)public class Demo01 { public static void main(String[] args) { //fun1(); Person p1 = new Person(); p1.name = "发了"; p1.sayHi(); Person p2 = new Person("啊哦",10); p2.sayHi(); } public static void fun1() { // { // // 局部代码块 限制变量的作用域 // int num = 10; // } // System.out.println(num); } } //暴力调试法 //小黄鸭调试法(逻辑调试) class Person{ String name; int age; // 无参 和 有参构造方法 // 介绍自己方法 // 吃 public Person() { name = "奥迪"; age = 16; System.out.println("我是无参的构造方法"); } public Person(String name , int age) { this.name = name; this.age = age; System.out.println("我是有参的构造方法"); } public void sayHi() { System.out.println(name + " " + age); } public void eat() { System.out.println("人--吃饭"); } //构造代码块 { System.out.println("我执行了吗?"); } //静态代码块 static { System.out.println("我是静态代码块"); } }其打印结果为
public class Demo02 { static { System.out.println("我是main方法的静态代码块"); } public static void main(String[] args) { System.out.println("我是main方法"); Test test1 = new Test(); test1.name = "xx"; Test test2 = new Test("dd"); } } class Test { String name; public Test() { System.out.println("我是 test类 无参构造方法"); } public Test(String name) { this.name = name; System.out.println("我是 test类 有参构造方法"); } { System.out.println("我是 test类 构造代码块"); } static { System.out.println("我是test类 静态代码块"); } }
打印顺序为
先运行main函数,而在此之前需要在方法区将Demo02.class运行,根据之前所说的,在随着类的加载,其静态构造代码块将会率先执行,打印①"我是main方法的静态代码块",之后调用main函数先打印②"我是main方法",随后创建一个对象test,而创建对象之前,又需要先在方法区加载Test类,而类中又有static修饰的静态代码块,所以打印③"我是test类 静态代码块",随之打印④"我是test类 构造代码块",类中代码块执行完毕后,随即创建完无参对象.打印⑤"我是test类 无参构造方法".之后又创建test2对象,同上,打印⑥"我是test类 构造代码块",⑦"我是test类 有参构造方法".
二 面向对象特征之继承
面向对象的特征为:封装,继承,多态
继承:
1.可以进行传递
2.继承的是 属性 和 行为(不是全部)
3.继承 建立 类和类之间的关系
继承的好处:
1.减少代码量
2.提高工作效率
3.增强了类与类之间的关系(让类和类的关系更加紧密)
继承的弊端:
提高内聚:希望一个类中,方法与方法之间联系加强
降低耦合:希望类与类之间减少联系
而继承违反了 低耦合.
什么时候使用继承?
继承:一定要符合 逻辑(比如:苹果 -子类 是 水果 -父类)
如若两个类没有合适的继承关系的话,可以考虑创建并继承一个第三类.
比如 项目经理 和 程序员,没有合适的父子类的逻辑关系,这是可以增加并继承一个员工类.
注意:
1.Java中 只允许 单继承(类与类)(通过接口实现多继承)
Java中 还允许 多层继承(继承链) A->B->C
2.当你想只使用共有方法和属性时,一般选择 使用继承链最顶端的类
3.当你想使用特有方法的时候, 一般选择 使用继承链最末端的类
4.如果一个类没有写继承 ,那么这个类 默认继承 Object类(基类)
三 继承中的构造方法
注意:构造方法是不能继承的
当创建子类对象的时候,为了保证继承的完整性(不管你在创建子类对象的时候,使用的是无参还是有参构造)
系统会默认帮你调用 父类中的 无参 构造方法
public class Demo05 { public static void main(String[] args) { Son son = new Son(); System.out.println("-----------------动感光波------------------"); Son son1 = new Son("小新"); } } class Father{ String name; public Father() { System.out.println("我是Father类的无参构造方法"); } public Father(String name) { this.name = name; System.out.println("我是Father类的有参构造方法"); } public void sayHi() { System.out.println(name); } } class Son extends Father{ public Son() { //系统帮你在 构造方法的第一行,写了一句代码 //如果你不写,系统会默认帮你加上 super();//调用父类的构造方法 System.out.println("我是Son类的无参构造方法"); } public Son(String name) { super(); this.name = name; System.out.println("我是Son类的有参构造方法"); } }
打印的结果是:
再来看这段代码
public class Demo06 { public static void main(String[] args) { TestB testB = new TestB(); testB.print(); } } class TestA{ int num1 = 10; int num2 = 20; public void fun() { System.out.println("我是父类的方法"); } } class TestB extends TestA{ int num2 = 30; public void print() { System.out.println(this.num1); System.out.println(this.num2); //直接调用父类的属性 使用super关键词 System.out.println(super.num2); //super也可以调用父类的方法 super.fun(); } }
super和this
super在子类中代表的是 父类的对象
this在子类中,可以调用子类的属性 和 方法
(当子类中没有这个属性 或者方法的时候,就去父类中寻找,找到就用,没找到就报错)
其打印的是:
如果父类没有无参的构造方法,此时只需要在子类的构造方法中第一行,调用一下父类构造方法
public class Demo07 { public static void main(String[] args) { Audi audi = new Audi(); } } class Car{ String name; // public Car() { // System.out.println("我是Car的无参"); // } public Car(String name) { this.name = name; System.out.println("我是Car的有参"); } } class Audi extends Car{ public Audi() { //只要你在构造方法的第一行 //调用一下父类构造方法(无参 有参都行) super("双钻"); System.out.println("我是Audi的无参"); } public Audi(String name) { super("四钻"); this.name = name; System.out.println("我是Audi的有参"); } }
四 方法重载和重写
方法重载(Overload)(在一个类中进行)
方法重写(Override)(前提:至少两个类 并且还有继承关系)
方法重写相当于对父级的该方法进行升级
重写:跟父类的写法完全一致
书写一个类,都写什么方法?
有参无参构造方法
set/get方法
重写toString方法输出属性
public class Demo08 { public static void main(String[] args) { TestD testD = new TestD(); testD.print(); } } class TestC{ public void print() { System.out.println("我是C类的 print方法"); } } class TestD extends TestC{ public void print() { //重写父类的方法时 //调不调用父类的方法 要根据你的需求而定 //ios7 siri 只会说英文 //ios8 siri 英文,中文都能说了 super.print(); System.out.println("我是D类的 print方法"); IOS8 ios8 = new IOS8(); //咱们直接打印对象 //希望直接把这个类的 属性输出出来 System.out.println(ios8); ios8.siri(); } } class IOS7{ public void siri() { System.out.println("说英文"); } } class IOS8 extends IOS7{ //注解 标识这个方法是重写父类 @Override public void siri() { super.siri(); System.out.println("说中文"); } public void fun() { } //这个方法 一般用来输出 本类中的属性 @Override public String toString() { //调用的是父类的方法 //打印出来 全类名@16进制的hashcode码 return "我就想看看属性"; } }
五 关键字final
1.可以修饰方法 方法不能被重写
2.修饰类 类不能被继承
3.修饰变量 变量不能修改
final修饰引用数据类型,不能进行重新指向(地址不能修改)
对象中的属性不会影响修改
public class Demo09 { public static void main(String[] args) { // final int num = 10; // num = 20; } } class TestE{ //堆内存分配默认值 是无效的默认 // final修饰成员变量的时候,需要赋值 // 赋值初始值,有三种方式 //一般使用final会直接定义成静态常量 //使用类名直接调用 方便 //常量命名规范 所有字母大写 多单词用下划线分开 // final int num = 10; public static final int MAX_VALUE = 10; public final void fun() { } public TestE() { //可以在构造方法中对变量进行赋值 // num = 10; } { //也可以在构造代码块中进行赋值 // num = 10; } } class TestF extends TestE{ // private void fun() { // // } }