1.代码块
概念: { }中包含一段代码
代码块的分类:
a:普通代码块:定义在方法中的代码块。
当一个方法中代码过长,为了避免变量重名,使用普通代码块。
b:构造块:定义在类中的代码块。
构造块写在构造方法之前,构造块比构造方法先执行。
eg:
class People{
String name;
int age;
{
System.out.println("构造块");
}
public People(String name, int age){ //带参构造,初始化属性
this.name=name ;
this.age =age ;
System.out.println("构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
People people =new People("xiaoming",17);
}
}
c:静态块:使用static修饰的代码块。
static{
}
静态代码块在编译阶段进行加载,而非静态代码块在运行阶段加载。所以在代码中,不论静态代码块和非静态代码块的前后顺序如何,所有的静态块比非静态块先执行。
eg:
class People{
String name;
int age;
//非静态代码块
{
System.out.println("非静态代码块");
}
//静态代码块
static{
System.out.println("静态代码块");
}
}
public class TestDemo {
public static void main(String[] args) {
People people =new People();
}
}
2.内部类
概念:内部类就是一个类里面又有一个类,里面的类就叫内部类。
eg:
class Out {
class In {
}
}
内部类藏在外部类里面,在外面看不见内部类,那么怎么访问到内部类的方法和属性呢?
要想访问一个类的方法和属性,就得有这个类的对象。首先在外部类中写一个方法,在这个方法中创建一个内部类的对象,用这个内部类对象来调用内部类的方法。然后在main中创建外部类的对象,用外部类对象调外部类方法。而这个外部类方法就可以访问到内部类方法了。
具体举例:
class Out{ //外部类
private String name="haha";//直接初始化属性,没有使用构造
class In{ //内部类
public void print ( ){ //普通方法
System.out.println(name); //方法中调用外部类的name私有属性,访问并输出name的内容
}
}
//在外部类中定义一个方法,来产生内部类对象,用这个内部类对象调用内部类中的print()方法
public void fun ()
In in=new In( ); //创建内部类对象
in.print();
//用内部类对象调用内部类中的print()方法
}
}
public class TestDemo {
public static void main(String[] args) {
Out out=new Out(); //外部类对象
out.fun();
}
}
由上段代码也可以看出:内部类可以访问外部类的私有属性。
内部类的分类:
a:成员内部类:
成员内部类中一般不能含有static变量和方法,因为static修饰的方法和变量都是在编译阶段加载,而外围都是非static,在运行阶段才执行,所以这样是矛盾的,是不可取的。
但是给static之前加上final,就可以了,因为它在编译期间就是一个确定的值了。
b:静态内部类:
静态内部类就是一个普通内部类被static所修饰。被static所修饰,就表示它的对象创建不依赖外部类对象。
eg:
class Outer{ //外部类
private static String name="hello";
static class Inner{ //内部类
public void fun(){ //内部类方法
System.out.println("hello");
}
}
}
public class TestDemo2 {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner();//创建内部类对象
inner.fun(); //内部类对象调用内部类方法
}
}
c:方法内部类:
顾名思义,方法内部类就是在外部类的方法中包含一个内部类。
d:匿名内部类:
匿名内部类就是一个没有名字的方法内部类。
3.继承
概念:继承相当于现实生活中的遗产继承。一个类继承另一个类就会得到它的方法和属性,并且也可以有自己的方法和属性。
比如有两个类,人和学生,学生和人之间有很多相同之处。学生一定是人,但人不一定就是学生。学生就是人的一种扩展,学生具有和人一样的属性和方法,但同时学生又有更多优于人的属性和方法。要是两个类分开来书写,必定会有很多重复的代码。此时就可以用到继承来优化代码。
继承的语法:class 子类 extends父类
子类也被称为派生类,父类也被称为超类、基类。
eg:
class People {//基类
private String name;
private int age;
public People() {
}
public People(String name, int age) {
this.name=name;
this.age=age;
}
public void fun() {
System.out.println("我是父类方法");
}
}
// Student类继承People类
class Student extends People {
private String school; //扩充新的属性
public Student(String school){
super();//此语句在调用无参构造时有没有都一样,但基类如果没有无参构造,这时super()就要指出所调用的构造
this.school=school;
}
public void fun2(){
System.out.println("我是子类方法"); //子类新扩充的方法
}
}
public class TestDemo {
public static void main(String[
] args) {
Student student = new Student("starschool");
student.fun(); //调用父类方法
Student student1 = new Student("starschool");
student1.fun2();//调用子类方法
}
}
子类对象在进行实例化前一定会首先实例化父类对象。默认调用父类的构造方法后再调用子类构造方法进行子类对象初始化。
继承注意事项:
a:一个子类只能继承一个父类
b:Java不允许多重继承,但允许多层继承
eg:
C同时想继承A和B
class B extends A{ }
class C extends B{ }
c:在进行继承的时候,子类会继承父类的所有结构,包括私有属性、普通方法,但是不继承父类的构造。
4.覆写
概念:如果子类定义了与父类相同的方法或属性的时候,这样的操作就称为覆写。(方法名相同、参数列表相同、返回值相同)此时调用此方法就是调用覆写后的方法,如果要调用父类的,要加super.方法名()
eg:
class People {
private String name;
private int age;
public void fun() {
System.out.println("我是父类方法");
}
}
class Student extends People {
public void fun(){
System.out.println("我是子类方法");
}
}
public class TestDemo{
public static void main(String[] args) {
new Student().fun();
}
}
super关键字:
super除了调用父类构造,还可以在覆写的操作过程中,子类使用super.方法/super.属性,调用父类中的同名方法或属性。
final关键字:
a:使用final修饰类、方法、属性
b:final成员变量必须在声明的时候初始化或者在构造器中初始化
c:使用final定义的类不能有子类
d:final一旦修饰一个类之后,该类的所有方法默认都会加上final修饰。
e:使用final定义的方法不能被子类所覆写。
f:使用final定义的变量就成为了常量,不能被修改。
g:定义常量,常量全用大写字母。
5.多态
概念:基类引用 引用派生类对象,并且基类和派生类有同名的覆盖方法。
eg:
class People {
public void fun() {
System.out.println("我是父类方法");
}
}
class Student extends People {
public void fun(){
System.out.println("我是子类方法");
}
}
public class TestDemo4 {
public static void main(String[] args) {
People people=new Student();//基类引用引用派生类对象
people.fun(); //引用谁的对象就调用谁的方法
}
}