一.代码块
1.局部代码块
书写位置:方法中
作用:限制作用域
2.构造代码块
书写位置:类中方法外
代码的执行顺序:
1️⃣.系统调用的
2️⃣.只要创建对象就会调用
3️⃣.构造代码块在构造方法之前被调用
3.静态代码块
使用关键词 static修饰的代码块
位置:类中方法外
调用顺序:
1️⃣.随着类的加载而加载
2️⃣.只加载一次
3️⃣.在构造代码块之前执行
应用场景:加载驱动(加载数据库驱动--一个类)
4.同步代码块(多线程)--暂时不做介绍
private static void fun1() {
{
int num = 10;
System.out.println(num);
}//局部代码块 可以限制变量的作用域
}
小黄鸭调试法:(逻辑调试)
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Sakura";
p1.sayHi();
Person p2 = new Person("Naruto",18);
p2.sayHi();
}
class Person{
String name;
int age;
//无参和有参的构造方法
public Person() {
name = "Naruto";
age = 18;
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 + "hahahahaha");
}
//吃
public void eat() {
System.out.println("吃东西");
}
//构造代码块
{
System.out.println("我是 构造代码块");
}
//静态代码块
static {
System.out.println(" 我是静态代码块");
}
}
看一下执行后的结果,思考一下执行的顺序:
example:
public class Demo{
static {
System.out.println("我是main方法的静态代码块");
}
public static void main(String[] args) {
System.out.println("我是main 函数");
Test test1 = new Test();
Test test2 = new Test("Naruto");
}
}
class Test{
String name;
public Test(){
System.out.println("我是Test类 无参构造方法");
}
public Test(String name){
System.out.println("我是Test类 有参构造方法");
}
{
System.out.println("我是Test类 构造代码块");
}
static {
System.out.println("我是Test类 静态代码块");
}
}
打印结果:
二.继承
回顾一下面向对象的特征:
封装 继承 多态
继承:
1.可以进行传递
2.继承的是属性和行为(不是全部)
子类可以继承父类的所有成员变量和成员方法,但不能继承父类的构造方法
3.继承 建立类和类之间的关系
继承的好处:
1.减少代码量(提高代码的复用性)
2.提高工作效率
3.增强了 类与类之间的关系(让类和类之间的关系更加紧密)
继承的弊端:
(提)高内聚:希望一个类中 方法与方法之间的联系加强
(降)低耦合:希望类与类之间 减少联系
以上只是代表一种思想 并不是绝对的实现
什么时候使用继承?
继承 一定要符合逻辑 把相同的代码抽成一个类 再使用继承
关键字:extends 父类名字
example:猫狗之于动物
把共有的属性如:名字 毛色 抽成一个父类
class Animal{
String name;
String color;
public void sayHi() {
System.out.println(name + "..." + color);
}
}
class Cat extends Animal{
public void speak() {
System.out.println("喵喵喵");
}
}
class Dog extends Animal{
public void speak() {
System.out.println("汪汪汪");
}
java中只允许单继承(通过接口实现多继承)
java中允许多层继承(继承链) A-->B-->C
当你想只使用功能有方法和属性时 使用哪个类的对象?
一般选择使用继承链 最顶端的类
当你想使用特有方法的时候 使用哪个类的对象?
一般选择使用继承链 最末端的类
如果一个类没有写继承 那么这个类默认继承Object类(基类)
public static void main(String[] args) {
DemoA a = new DemoA(); Object
//当直接打印对象的时候
//相当于调用了 Object类中的 toString方法
System.out.println(a);
}
打印出来的是:
全类名@16进制的hashcode码
三.继承中的构造方法
注意:构造方法是不能被继承的
当创建子类对象的时候,为了保证继承的完整性
(不管在创建子类对象的时候 使用的是无参还是有参构造)
系统会默认帮你调用 父类中的无参构造方法
example:
public class Demo{
public static void main(String[] args) {
//Father father = new Father();
Son son = new Son();
System.out.println("-----------------");
Son son1 = new Son("儿子");
}
}
class Father{
String name;
public Father() {
System.out.println("我是儿子他爸爸的无参构造方法");
}
public Father(String name) {
this.name = name;
System.out.println("我是昂他爸爸的有参构造方法");
}
public void sayHi() {
System.out.println(name);
}
}
class Son extends Father{
String name;
public Son(){
//系统帮你在构造方法的 第一行 写了一句代码
//如果不写 系统会默认帮你加上
super();//调用了父类的构造方法
System.out.println("我是儿子的无参构造方法");
}
public Son(String name){
super();//调用父类的构造方法
this.name = name;
System.out.println("我是儿子的有参构造方法");
}
}
系统会在构造方法的 第一行 写一句代码:super();
如果不写 系统会默认帮你加上
打印结果:
四.super和this
super在子类中代表的是父类的对象
this在子类中可以调用子类的属性和方法
(当子类中没有这个属性 和方法的时候 去父类找 找到就用 找不到就报错)
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.fun();
}
}
可以在子类中构造方法的第一行 调用一下父类的构造方法(有参 无参都可以)
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("我是奥迪的无参");
}
public Audi(String name) {
super("三钻");
this.name = name;
System.out.println("我是奥迪的有参");
}
}
五.方法重载和方法重写
方法重载:(Overload)(在一个类中进行)
方法重写:(Override)(前提:至少两个类 并且还要有继承关系)
跟父类的方法完全一致
作用:对父类的该方法进行升级
example:
class IOS7{
public void siri() {
System.out.print("说英文");
}
}
class IOS8 extends IOS7{
String name;
//注解:表示这个方法是重写父类
@Override
public void siri() {
super.siri();
System.out.print("说中文");
}
//这个方法一般用来 输出本类中的属性
@Override
public String toString() {
//调用的是父类方法
//打印出来是全类名@16进制的hashcode码
return "name = "+name;
}
}
重写父类的方法时 调不调父类的方法要根据你的需求而定
直接打印对象 希望是直接把类的属性输出出来
写一个类都写什么方法?
无参 有参 构造方法
set/get方法
重写toString方法输出属性
private修饰的属性会被子类继承 但是子类无法直接访问
可以间接访问 通过set/get方法来间接访问
六.关键字final
final:
1.修饰方法 方法不能被重写
2.修饰类 类不能被继承
3.修饰变量 变量不能被修改
final修饰引用数据类型不能进行重新指向(地址不能修改)
对象中的属性不会影响修改
一般使用final的时候 会直接定义成静态常量
使用类名直接调用 方便
常量的命名规范 所有字母大写 多单词用下划线分开
ex:
public static final int MAX_VALUE = 10;
堆内存分配的默认值 是无效的默认值
final修饰成员变量的时候 需要赋初始值
赋初始值 有三种方式:
1.声明常量
2.在构造方法中进行赋值
3.在构造代码块中进行赋值