一、 代码块
1.什么是代码块
在程序中使用“{}”括起来的一段代码就称为代码块,根据代码块出现的位置或声明的关键字的不同,分为四种:
1 .局部代码块: 书写在方法内 用来限制变量的作用域
2.构造代码块: 类中方法外 , 由系统调用 只有创建对象 就会调用,并且构造代码块在构造方法之前调用.
作用:如果每个对象都有相同的方法要去执行,可以在构造代码块中调用(开发中几乎没有这样的场景)
3.静态代码块: 类中方法外, 使用static修饰的代码块 ,随着类的加载而加载,并且只加载一次,在构造代码块之前执行.
4.同步代码块:线程相关在多线程中会使用.
2.接下来看下各种代码块在程序中的位置与执行顺序
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方法的静态代码块
我是main方法
我是test类 静态代码块
我是 test类 构造代码块
我是 test类 无参构造方法
我是 test类 构造代码块
我是 test类 有参构造方法
二 、继承
1.继承的定义 继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
例如:
比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。
2.继承的特征
1.具有传递性
2.继承的是属性和行为(不是全部)
3.建立类与类之间的关系
3.继承的好处
1.减少代码量(代码的复用性)
2.提高工作效率
3.增强了类与类之间的关系(让类与类之间的联系更加紧密)
4.继承的缺点
提|高内聚 : 希望一个类中 方法与方法的联系加强
降|低耦合 : 希望类与类之间减少联系;
继承违反低耦合;
5.继承:一定要符合逻辑 判断是否可以继承 可以使用 xxx是xxx 判断是否符合逻辑
关键字 static
6.注意事项
java 中 只允许单继承(类与类) (通过接口可以实现多继承)
Java 中 允许多层继承 (继承链) a-->b-->c
当你想只使用共有的方法 和属性 使用哪个类的对象?
一般选择继承链的最顶端的类
当你想只使用特有的方法 和属性 使用哪个类的对象?
一般选择继承链的最末端的类
如果一个类没有写继承类 默认继承 Object类(基类)
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("汪汪");
}
}
在上面的代码中 dog类与cat类都继承了Animal类中 name属性,color属性 与sayhi 行为. 而且在两个子类中有自己独有的speak 行为.
注意事项:
继承中 构造方法时无法继承的 父类的构造方法名同子类的方法名是不同的.
当创建子类对象时,为了保证继承的完整性,
不管你在创建子类对象时使用无参还是有参系统会默认帮你调用 父级的无参构造方法;
7.super 和 this :
super 在子类中代表的是父类的对象
this 在子类中可以调用子类的属性和方法 ,
(当在子类中 没有这个属性 或者方法时 就去父类中寻找 ,找到就用 找不到就报错);
public class Demo06superAndThis {
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); //此时this继承父级的num = 10
System.out.println(super.num2);// 此时super 表示父级TestA num2 继承父级的num2 =20
System.out.println(num2);// num2前 this可省略 此时this字子类中找到 num2=30
// super 也能调用父类的方法
super.fun();
}
}
如果父类没有创建无参构造方法 ,需要在子类构造方法第一行调用父类的构造方法(有参 无参都行).如下:
public Audi() {
//只要你在子类构造方法第一行
// 调用父类的构造方法(有参 无参都行)
super("BMW");
System.out.println("我是Audi类的无参构造方法");
}
三 、方法重写
方法重写 Override(前提:至少两个类 并且有继承关系)
方法重载 Overload(一个类中进行)
方法重写的作用:
跟父类的方法完全一样.
书写一个类 都写什么方法?
有参 无参 构造方法
set/get 方法
重写 toString 方法输出属性
例如创建一个父类 两个子类
老师类 学生类
无参 有参构造 set/get方法 成员变量私有化 介绍自己的方法
属性:姓名,年龄
行为:吃饭
老师有特有的方法:讲课
学生有特有的方法:学习
public class Person {
// private 修饰的属性 会被子类继承 但是子类无法访问
//可以间接访问 通过set/get
private String name; //姓名
private int age; //年龄
public void eat() {
System.out.println("吃饭");
}
//无参 /有参
public Person() {
}
public Person(String name,int age) {
this.name=name;
this.age = age;
}
// set/get 方法
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "我是"+name+".."+"我有"+age;
}
}
class Student extends Person{
//有参 无参
public Student() {
//无参构造
}
public Student(String name,int age) {
// 调用父类有参的构造方法 完成对成员变量的赋值
super(name,age);
}
public void study() {
System.out.println(this.getName() + "上课");
}
}
class Teacher extends Person{
//有参 无参
public Teacher() {
//无参构造
}
public Teacher(String name,int age) {
// 调用父类有参的构造方法 完成对成员变量的赋值
super(name,age);
}
//上课方法
public void teach() {
System.out.println(this.getName()+"讲课");
}
}
四 关键词 final
final是个关键字(绝育),
修饰类:不能被继承
可以修饰变量:不能被修改
修饰方法:修饰方法时不能被重写
修饰 引用数据类型 不能进行重新指向(地址无法修改)
对象中的属性不会影响修改.
final修饰的变量相当于是常量(不能修改的量),
0在final是无效的默认值,final赋值初值有三个方法:1.直接赋值初值 2.在构造方法中赋值 3.构造代码块中修改
一般用来定义常量
public static final double PI=10;
常量命名规范,一个单词的话全部大写,多个单词的话用下划线分开,并且单词要全部大写;