1. abstract 修饰的类称为抽象类。
① 抽象类不能单独创建对象,只能声明引用。
② 抽象类中可以定义成员变量、成员方法。
③ 抽象类中有构造方法,但是构造不是单独创建对象时使用,
而是创建子类对象,先去创建父类时,子类调用。
2. abstract 修饰的方法称为抽象方法。
① 抽象方法只有声明,没有实现(注意:连{}都没有 )。
访问修饰符 abstract 返回值类型 方法名(形参);
注意:访问修饰符 abstract没有位置先后要求。
② 抽象方法只能定义在抽象类中。
注意:① 子类继承抽象类,必须实现抽象类中所有的抽象方法,
否则子类也必须是抽象类。
② 抽象类的作用:强制使用多态。
eg:
package demo2017111;/*
* shape,求周长和面积
*/
public class Question_07 {
public static void main(String[] args) {
Shape[] s={new Circle(1),new Rect(1,1),new Square(1)};
for(int i=0;i<s.length;i++){
System.out.println("周长:"+s[i].girth()+"面积:"+s[i].area());
}
}
}
abstract class Shape {
public abstract double girth(); //周长
public abstract double area(); //面积
}
class Circle extends Shape{
private double r;
public Circle(){}
public Circle(double r){
this.r=r;
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public double girth(){
return 2*r*Math.PI; //圆的周长
}
public double area() {
return Math.PI*r*r; //圆的面积
}
}
class Rect extends Shape{
private double length;
private double width;
public Rect(){}
public Rect(double length,double width){
this.length=length;
this.width=width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double girth(){
return 2*(length+width); //矩形的周长
}
public double area(){
return length*width; //矩形的面积
}
}
class Square extends Rect{
private double bianChang;
public Square(){}
public Square(double bianChang){
this.bianChang=bianChang;
}
public double getBianChang() {
return bianChang;
}
public void setBianChang(double bianChang) {
this.bianChang = bianChang;
}
public double girth(){
return 4*bianChang; //正方形的周长
}
public double area(){
return bianChang*bianChang; //正方形的面积
}
}
二、 static(静态的)
1. static 修饰的属性称为 静态属性 或是 类变量。
① 语法:访问修饰符 static 数据类型 属性名;
注意:访问修饰符 static没有位置先后顺序。
② 特点:与创建多少对象无关,是全类共有的属性。
③ 使用:类名.静态属性名;
2. static 修饰的成员方法称为静态方法 或是 类方法。
① 语法:访问修饰符 static 返回值类型 方法名(形参列表){
//方法的实现....
}
注意:访问修饰符 static 没有位置先后。
② 使用:类名.静态方法名(实参);//建议使用
对象名.静态方法名(实参);
③ 静态方法中只能直接访问本类中静态成员(静态方法、静态属性);
静态方法中不能直接访问非静态的成员(属性、方法)。
④ 非静态的方法中可以直接访问本类中静态成员(静态属性和静态方法)。
⑤ 静态方法中不能使用 this/super
⑥ 静态方法允许被继承,只能被静态方法覆盖,并且没有多态。
3. static 修饰的代码块称为静态代码块。
初始化代码块(动态代码块):【了解】
a. 位置:定义在类以内,方法以外。
b. 作用:创建对象时,和属性按照定义的先后顺序完成属性的初始化工作。
静态代码块:【开发重点】
a. 位置:定义在类以内,方法以外,被static。
b. 作用:类加载时,静态代码块和静态属性按照定义的先后顺序完成静态属性的
初始化工作。
c. 类加载:当JVM第一次使用一个类时,通过classPath找到.class文件,
从.class文件中获取类的相关信息(类名、包名、属性、方法相关、
父类、接口等),保存在JVM中,类加载只进行一次。
d. 类加载的时机:
I. 第一次创建一个类的对象时,先进行类加载,再创建对象
package demo2017115;
/*
* 类加载时机1,创建对象,先进行类加载,再创建对象,类加载只进行1次
*/
public class ClassShiJi1 {
public static void main(String[] args) {
Super super1 = new Super();
}
}
class Super {
//静态代码块
static {
System.out.println("先进行类加载");
}
public Super() {
super();
System.out.println("再创建对象");
}
}
II. 第一次使用一个类中的静态成员(静态方法、静态属性),会导致类加载。
package demo2017115;
/*
* 类加载时机2,访问静态属性和静态方法,导致先进行类加载
*/
public class ClassShiJi1 {
public static void main(String[] args) {
Super super1 = new Super();
System.out.println(super1.i);
super1.Super();
}
}
class Super {
static int i=0;
public static void Super() {
System.out.println("再访问再访问静态类成员");
}
//静态代码块
static {
System.out.println("先进行类加载");
}
}
① 创建子类对象
② 使用子类中静态成员
package demo2017115;
/*
* 类加载时机3,加载子类先下载父类:创建子类对象,使用子类中的静态成员
*/
public class ClassShiJi1 {
public static void main(String[] args) {
SuperFuLei super1 = new Super();
System.out.println(super1.name);
//父类强转成子类
Super su=(Super)super1;
System.out.println(su.i);
Super.Super();
}
}
class SuperFuLei{
static String name="张广伟";
static {
System.out.println("先进行类加载");
}
}
class Super extends SuperFuLei{
static int i=0;
public static void Super() {
System.out.println("再访问金泰属性");
}
//静态代码块
static {
System.out.println("先进行类加载");
}
}
总结对象创建的过程:【理解】
先类加载:
先加载父类:静态属性、静态代码块
加载子类:静态属性、静态代码块
再创建对象:
先创建父类对象:
初始化属性:执行动态代码块
调用父类的构造方法。
再创建子类对象:
初始化属性:执行动态代码块
调用子类的构造方法。
思考:System.out.println();实现原理????
System:类名
out:System类中静态属性,对象类型
println:out类型中的方法
三、 final(最终的、最后的)
1. final修饰变量(局部变量、实例变量、类变量)
final修饰的变量是作用范围的常量,只允许使用,不允许改变。
final修饰的实例变量:没有默认值
赋值的机会:
a. 声明的同时对其初始化
b. 在构造方法中对其初始化
注意:使用构造方法对其初始化,必须保证每一个构造方法都
对其初始化。
final修饰的类变量:没有默认值
赋值的机会:
a. 声明的同时对其初始化
b. 静态代码中对其初始化
注意:final修饰的变量类型为基本数据类型:数值不允许改变;
final修饰的变量类型为对象数据类型:地址不允许改变。
2. final修饰方法:可以被继承,但是不允许被覆盖。
3. final修饰类:不允许被继承,即没有子类。
final修饰类:System,String,Math...