书写位置:方法中
作用:限制作用域
书写位置:类中 方法外
代码的执行顺序:
①系统调用
②只要创建对象 就会调用
③构造代码块 在 构造方法 之前被调用
作用:当你有方法 需要每一个对象都调用的时候,可以将这个方法在构造代码块中调用(不常用)
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的有参");
}
}
方法重写相当于对父级的该方法进行升级
重写:跟父类的写法完全一致
书写一个类,都写什么方法?
有参无参构造方法
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 "我就想看看属性";
}
}
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() {
//
// }
}