程序代码块
1 普通代码块(一般写在普通方法里)
2 构造代码块(直接在类中定义的代码块,可以看成是一个类的成员,它会被调用多次,并比构造方法先执行)
3 静态代码块(在一般类里,或者是在启动类里,每个静态块只执行一次)
4 同步代码块(多线程中应用)
5 Tips:静态块先于主方法执行,静态块先于普通块执行,静态块也先于构造块执行。
class Person
{ void f( )
{ if (true)
{ /*普通代码块*/
int x=10;
System.out.println(x);
}
int x=12;}
}
class Test-6.1
{ public static void main(String[] args)
{System.out.println( ); }
}
class Person
{ String name;
public Person()
{ System.out.println("this is a gouzao fangfa"); }
{ /*比构造方法先执行,并且是多次执行(每生成一个对象就执行一次)*/
System.out.println("this is a gouzao code");
}
}
class Test-6.2
{ public static void main(String[] args)
{ new Person();
new Person();
System.out.println();
}
}
class Person
{ String name;
public Person()
{ System.out.println("this is a gouzao fangfa"); }
{ System.out.println("&&&&&this is a gouzao code");}
static
{ System.out.println("^^^^this is a jingtai code"); }
/*静态块,在构造块前加上static,比构造块和构造方法先执行,并且只执行一次*/
}
class Test-6.3
{ public static void main(String[] args)
{ new Person();
new Person();
System.out.println(); }
}
class Person
{ String name;
public Person()
{ System.out.println("this is a gouzao fangfa"); }
}
class Test-6.4
{ public static void main(String[] args)
{ System.out.println("begin");
new Person();
new Person();
System.out.println("end"); }
static
{ System.out.println("this is a jingtai QiDong code"); }
/*可用于静态变量初始化,主类中的静态方法块比main方法还先执行,且位置不影响运行顺序*/
}
class Test-6.5
{
static
{
System.out.println("I am here!");
System.exit(1);
}
}
//不用主方法就能输出I am here!
/*强行退出系统,这样不需执行main()也不会出现异常,若没System.exit(1);输出static内容后,提示出错。少用,尽量有main()*/
内部类(内置类)
1 成员内部类(实例内部类):可以访问外部类的成员(包括私有的);外部类不能直接访问内部类成员变量,必须构造方法修改
2 静态内部类(相当于外部类)
3 局部内部类(方法里)
4 匿名内部类(一般是在抽象类和接口的基础上使用)
class Outter
{ String name="huang";
//class Inner { System.out.println(name); }错误
class Inner
{ String name="guo"; //变量的就近原则
public void f( ) { System.out.println(name); } //运行结果:guo
} //生成的文件目录:
public void print( ) //Outter.class
{ Inner in = new Inner( ); in.f( ); } //Test-6.6.class
} //Outter$Inner.class
class Test-6.6
{ public static void main(String[] args)
{ Outter out = new Outter( ); out.print( ); }
}
class Outter
{ private String name="huang";
class Inner
{ String name ="guo";
public void f( )
{ System.out.println(name); //guo
System.out.println(Outter.this.name); } //huang
}
public void print( )
{ Inner in = new Inner( ); in.f( ); } }
class Test-6.7
{ public static void main(String[] args)
{ Outter out = new Outter( ); out.print( );
//Outter.Inner in = new Outter.Inner( ); in.f( );错误
} }
class Outter
{ private String name="huang"; //封装后内部类可直接访问
class Inner
{ String name ="guo";
public void f( ) { System.out.println(name);} } //guo
public void print( )
{ Inner in = new Inner( ); in.f( ); } }
class Test-6.8
{ public static void main(String[] args)
{ Outter out = new Outter( );
Outter.Inner in = out.new Inner();
in.f( );
/*等价于Outter.Inner in = new Outter().new Inner();
in.f( );*/
} }
class Outter
{ private String name="huang";
static class Inner
{ String name ="guo";
public void f( ) { System.out.println(name);} //guo
}
public void print( )
{ Inner in = new Inner( ); in.f( ); }
}
class Test-6.9
{ public static void main(String[] args)
{ Outter.Inner in = new Outter.Inner( );
in.f( );
}
}
class Outter
{ private String name="huang";
public void print( )
{ class Inner
{ String name ="guo";
public void f( ) { System.out.println(name);} //运行结果:guo
}
Inner in = new Inner( ); in.f( ); //生成的文件目录:
} //Outter.class
} //Test-6.10.class
class Test-6.10 //Outter$Inner.class
{ public static void main(String[] args)
{ Outter out = new Outter( );
out.print( ); }
}
class Outter
{ private String name="huang";
public void print( )
{ final String name="guo"; //一定要初始化
class Inner
{ public void f( ) { System.out.println(name); } }
/*不加final就写成System.out.println(Outter.this.name);*/
Inner in = new Inner( ); in.f( );
}
}
class Test-6.11
{ public static void main(String[] args)
{ Outter out = new Outter( ); out.print( ); } //guo
}
继承(extends)
1 Java只支持单继承,不允许多重继承(一个子类只能有一个父类)。但支持多层继承(传递性)
2 在生成子类对象之前,一定先生成父类对象
3 子类内存一定比父类内存大
4 子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法。子类实例化时,先调用父类的构造方法,再调用自己的构造方法(子类构造方法中隐藏一个super()方法,用于调用父类的构造方法)
class Person
{ String name;
private int age; //隐式继承,不能直接访问,可通过方法调用
public void setName(String name)
{ this.name=name; }
public void setAge(int age) //显式的继承
{ this.age=age; }
public String getName() { return this.name; }
public int getAge() { return this.age; }
}
class Student extends Person
{ private String school;
public void setSchool(String school)
{ this.school=school; }
public String getSchool() { return this.school; }
}
class Test-6.12
{
public static void main(String[] args)
{
Student s=new Student();
s.name="LJS";
//s.age=3; 错误
s.setAge(3);
System.out.println(s.getName()); //LJS
System.out.println(s.getAge()); //3
}
}
lass Person
{ private String name;
Person() { System.out.println("##i am a father##"); //}
Person(String name)
{ this.name=name;
System.out.println(name);
System.out.println("$$i am a father$$"); }
public void setName(String name) { this.name=name; }
public String getName() { return this.name; }
}
class Student extends Person
{ String school="GDPU";
Student()
{ super("LL"); System.out.println("**i am a son**"); }
}
class Test-6.13
{
public static void main(String[] args) //运行结果:
{ //LL
Student s=new Student(); //$$i am a father$$
s.setName("LJS"); //**i am a son**
System.out.println(s.getName()); //LJS
}
}
/*Student类中默认的构造方法是Student(){super();}
Super()的作用是子类调用父类的构造方法
super关键字
1 调用父类的构造(super() , this()),都必须放在第一行 。this()和super()不能写在一起
2 可以调用父类的成员(成员变量+成员方法)( super.x 或者 super.a( ) )
3 子类内存一定比父类内存大
lass A
{ int age;
public A(int age)
{ System.out.println("^^^AA^^^"); }
}
class B extends A
{ public B()
{ super(10);
System.out.println("****BB*****");}
}
class C extends B
{ public C()
{ super();
System.out.println("&&&CC&&&&");}
}
class Test-6.14
{
public static void main(String[] args)
{
System.out.println();
C c=new C();
}
}
//问,产生多少个对象??
//一个字符串常量就是一个匿名对象
class A
{ public A()//调用顺序2
{ System.out.println("^^^AA^^^"); }
}
class B extends A
{ public B()
{ this(1); //调用顺序1
//super();
System.out.println("****BB*****"); //调用顺序4
}
public B(int x) //调用顺序1
{ //super();默认,调用顺序2
System.out.println("********");//调用顺序3
}
}
class Test-6.15
{ public static void main(String[] args) //^^^AA^^^
{ B b=new B(); //********
System.out.println(); //****BB*****
}
}
class A
{ int age=10;
public A() { System.out.println("^^^AA^^^"); }
public void print() {System.out.println(age);}
}
class B extends A
{ int age=20;
public B() { System.out.println("***BB***"); }
}
class Test-6.16
{ public static void main(String[] args) //^^^AA^^^
{ B b=new B(); //***BB***
b.print(); //10
}
}
class A
{ int age=10;
public A() { System.out.println("^^^AA^^^"); }
}
class B extends A
{ int age=20;
public B() { System.out.println("***BB***"); }
public void print() {System.out.println(age);}
}
class Test-6.17
{ public static void main(String[] args) //^^^AA^^^
{ B b=new B(); //***BB***
b.print(); //20
}
}
class A
{ int age=10;
public A() { System.out.println("^^^AA^^^"); }
}
class B extends A
{ int age=20;
public B() { System.out.println("***BB***"); }
public void print() {System.out.println(super.age);}
}
class Test-6.18
{ public static void main(String[] args) //^^^AA^^^
{ B b=new B(); //***BB***
b.print(); //10
}
}
方法的改写
1 又名:重写/覆写/覆盖 override
2 方法的头完全相同,方法体不同(一定要发生在继承中的父类和子类之间)
3 当子类改写了父类的方法成功之后,当生成子类对象,调用的一定是子类改写过的方法
4 子类改写父类的方法时,子类的访问权限不能比父类更严格(private > default(friends) > public )
5 如果父类的方法是私有的,则不能被改写
class A
{ public void print()
{ System.out.println("%%%%father");}
}
class B extends A
{ public void print()
{ System.out.println("%%%%child%%%%");}
}
class Test-6.19
{
public static void main(String[] args)
{ B b=new B();
b.print(); //%%%child%%%
}
}
class A
{ void print()
{ System.out.println("%%%%father");}
}
class B extends A
{ public void print()
{ System.out.println("%%%%child%%%%");}
}/*若换成拿掉B类的public,则错误*/
class Test-6.20
{
public static void main(String[] args)
{ B b=new B();
b.print(); //%%%%child%%%
}
}
class Person
{ public void f() { say(); /*也可为this.say();*/ }
public void say()
{ System.out.println("father"); }
}
class Student extends Person
{ public void say()
{ System.out.println("student"); }
}
class Test-6.21
{ public static void main(String[] args)
{ Student s=new Student();
s.f(); //student
}
} //间接调用
class Person
{ public void f() { say();}
private void say()
{ System.out.println("father"); }
}
class Student extends Person
{ public void say()
{ System.out.println("student"); }
}
class Test-6.22
{ public static void main(String[] args)
{ Student s=new Student();
s.f(); //father
}
}
final关键字
1 修饰类,不能有子类(此时为最终类)
2 修饰方法,不能被子类改写
3 修饰成员变量,成为一个常量,不能被修改。(大写) 使用public static final声明的常量称为全局常量
4 final可以修饰非抽象类,非抽象成员方法和变量,但不能用来修饰构造方法。
5 注意:形参调用内部类,则形参前必须有final修饰
final class A //最终类
{
final int x=10;//变为常量
public static final int Y=10;//变为全局常量,,全局常量名应大写
public final void f(){ } //最终方法
}
/*class B extends A
{
//public void f() {x=100;}错误
}*/
class Test-6.23
{ public static void main(String[] args)
{ System.out.println(); }
}
对象转型
前提:一般发生在继承中
1 向上转型:父类的引用指向子类对象(小的赋给大,是系统自动)(隐式)(常用) 只能执行父类自己所拥有的成员
2 向下转型:不可直接向下转型,必须先发生向上的转型 (少用)
3 instanceof 作用: 判定对象是不是父类,子类的对象
class A
{ }
class B extends A
{ }
class Test-6.24
{
public static void main(String[] args)
{
//A a=new A();
A a=new B(); //儿子赋给父亲 向上转型,自动
System.out.println();
}
}
//向上转型,父类的引用指向子类对象
class A
{ }
class B extends A
{ }
class Test-6.25
{ public static void main(String[] args)
{
//B b=new A(); 错误,父类生成时,无法知道子类
A a=new B();
B b=(B)a;//把父类类型赋予子类需要强制类型转换,显式}
}
//向下转型
class A
{ public void say()
{System.out.println("father");}
}
class B extends A
{ String xiaomi = "5splus";
public void say() {System.out.println("son");}
public void play() {System.out.println("play");}
}
class Test-6.26
{ public static void main(String[] args)
{ A a=new B(); //把儿子看成父亲,实为儿子
System.out.println(a.xiaomi); //错误,子类独有,父亲无法代表
}
} //父类可代表子类,但实际运行权限仅限于父类范围