个人复习Day6
2.5 static 关键字
2.5.1.static 可以修饰变量,方法,静态块
2.5.2 static 修饰的变量叫静态变量(类变量)
在类加载的时候,分配内存,有默认值,可以访问,通常使用类
名访问,静态变量在实例化之前,构造方法可以使用静态变量
**练习:对象的计数器**
**思路:每创建一个对象就会自动调用一次构造函数,所以计数器放在构造方法中会自动计数**
public class Student {
int age;
public String name;
static int n=0;
public Student(){
n++;
System.out.println("这是第"+n+"对象");
}
}
public class TestStudent {
public static void main(String[] args) {
Student stu1=new Student();
stu1.name="yw";
stu1.age=18;
Student stu2=new Student();
stu2.name="aa";
stu2.age=10;
Student stu3=new Student();
System.out.println(Student.n);
}
}
2.5.3 static修饰方法
没有static修饰的方法,叫实例方法;static修饰的方法在类加载的时候分配内存,可以有类名调用,在静态方法中不能使用this,super
重写?不可以
重载?可以
继承?可以
2.5.4 静态块
static{
}
静态块是在类加载时解析执行,只执行一次
创建子类对象时:
父类的静态块-》子类的静态块-》父类的实例块-》父类构造方法-》子类实例块-》子类构造方法
public class Demo2 {
public static int i;
//实例块
{System.out.println("aaa");}
//构造方法
public Demo2(){System.out.println("bbb");}
//静态块
static{System.out.println("static");}
}
public class Demo3 extends Demo2{
static{System.out.println("static2");}
public Demo3(){System.out.println("demo3");}
}
public class TestDemo2 {
public static void main(String[] args) {
//System.out.println(new Demo2());
//System.out.println( Demo2.i);
//Demo2 d1=new Demo2();
//Demo2 d2=new Demo2();
Demo3 d3=new Demo3();
//Demo2 d3=new Demo3();
}
}
static
static2
aaa
bbb
demo3
D d应该为static D d;
按照顺序走,静态变量和静态块按先后顺序走
A1,C,D,C,B1,A2,A3,B2,B3
静态变量的初始化过程:
准备(标识变量的值)-》初始化
先标识变量的值,如果有初始化的值,直接初始化完成;如果没有初始化的值,标识变量的值,作为变量的值
public class A{
static int x=9;
static{
x=10;
y=90;
z=20;
}
static int y=100;
static int z;
public static void main(String[] args) {
System.out.println(x+"+"+y+"+"+z);
}
}
10+100+20
2.6 final关键字
final可以修饰类,变量,方法
可以修饰方法内的变量
常量:
class A {
//静态成员变量的初始化在class加载完成之前
//声明初始化完成或者在静态块中完成
//实例变量的常量在创建对象完成之前赋值就可以
//声明直接初始化
final int X=90;
final int Y;
{
Y=90;
}
final int Z;
public A(){
Z=90;
}
public A(int i){
Z=90;
}
}
final修饰方法:不能被重写
final修饰类:不能被继承
对于数组,final有特殊规则
public class Demo9 {
final int x=9;
//引用的地址不可以修改
//可以修改数据
final int[] a={1,2,3,4,5};
public void f(){
a[0]=2;
}
}
3.抽象类
3.1抽象方法
由abstract修饰的方法,叫抽象方法
3.2抽象方法的特点
没有方法体
3.3抽象类
由abstract修饰的类,叫抽象类
3.4抽象类的特点
不能创建对象
3.5抽象类必须有子类实现,要实现抽象类中所有抽象方法
注意:final、private、static不能修饰抽象方法
抽象类就是专门用来让子类继承的,static是不让子类继承的,final修饰的类不可以被继承,private权限是本类中,子类继承后无法访问private修饰的类
3.6抽象类中不是必须有抽象方法
练习:图形类
public abstract class Shape {
protected abstract int getArea();
protected abstract int getLength();
}
public class Rectangle extends Shape{
public int width;
public int height;
public Rectangle(int width, int height) {
super();
this.width = width;
this.height = height;
}
@Override
protected int getArea() {
// TODO Auto-generated method stub
return width*height;
}
@Override
protected int getLength() {
// TODO Auto-generated method stub
return 2*height+2*width;
}
}
public class Square extends Rectangle{
public Square(int width ) {
super(width, width);
// TODO Auto-generated constructor stub
}
}
public class TestShape {
public static void main(String[] args) {
Shape shape1=new Rectangle(4,5);
System.out.println(shape1.getArea());
Shape shape2=new Square(5);
System.out.println(shape2.getArea());
}
}
4.接口
JDK1.8之前接口里没有构造方法,只有抽象方法,1.8之后可以有普通方法
interface 接口名{
1.常量
常量默认由public static final修饰
2.抽象方法
抽象方法默认由public abstract修饰
3.可以定义普通方法(JDK1.8)
4.必须把接口中所有抽象方法都实现了才可以创造对象
5.子类要把所有抽象方法重写
如果不完全实现抽象方法,当前类必须定义为abstract类
6.如果两个接口中的方法名相同,那么子类重写同名方法
7.接口的实现类的父类和接口中都存在同名方法时,子类调用的方法为父类的方法
注意:类和接口之间满足:has a
接口和接口之间可以继承 extends
interface A{}
interface B extends A{}
类和接口实现,可以实现多个接口
class ectends Object implements A,B,C{}
}
函数式接口:接口中只有一个抽象方法
也可以使用注解定义函数式接口
//函数式接口,只有一个抽象方法,可以使用λ表达式
interface C{
int add(int x,int b);
}
总结:接口和抽象类的区别
1. 抽象类是定义对象的模板(所有对象),接口定义规范(不同类型的对象)
2. 抽象类不可以多继承,接口可以实现多个
3. 抽象类变量是普通变量,接口变量默认由public static final修饰
4. 抽象类可以定义抽象方法,由abstract修饰,也可以定义普通方法。接口在JDK1.8之前只能定义抽象方法,之后可以定义普通方法,但是default或static修饰,并且默认是public修饰的
5. 抽象类有构造方法,接口没有抽象方法
6. 抽象类可以定义块,接口不可以定义块