<1>代码块:分为局部代码块、构造代码块、静态代码块
局部代码块:方法中出现,限定变量生命周期,提高内存利用率;构造代码块:类中方法外出现,优先于构造函数执行。可以将多个构造方法中相同的方法存放到一起,每次调用都执行;每创建一次对象,就先执行构造代码块,然后执行构造方法。主方法内的静态代码块随类加载而加载,优先于主方法执行,只执行一次。可以用于给类初始化,一般用于加载驱动。
/*
执行顺序:静态代码块 构造代码块 构造方法
下例中执行的结果为:主函数里的静态代码块,我是main方法,person静态代码块
person构造代码块,person构造方法,person构造代码块,person构造方法
*/
class Demo {
static {
System.out.println("主函数里的静态代码块");
}
public static void main(String[] args) {
System.out.println("我是main方法");
Person s1 = new Person();
Person s2 = new Person();
}
}
class Person {
static {
System.out.println("Person 静态代码块");
}
{
System.out.println("Person 构造代码块");
}
public Person() {
System.out.println("Person 构造方法");
}
}
<2>继承(extends)
优点:提高代码的复用性,使类之间产生关系,是多态的前提;缺点: Java开发的原则是:高内聚,低耦合,继承增加了类之间的耦合性。
Java
中继承的特点:
(1)Java
只支持单继承,不支持多继承,但支持多重继承。
(2)
继承中,最底层类拥有所有类的属性和方法;最高层类拥有整个类的共性特点 。
(3)
子类只能继承父类所有非私有成员,但子类可以使用setxxx()
和getxxx()
访问父类私有属性。
(4)
不要为了部分功能去继承,继承体现了一种“is a”
关系。
(5)
注意:子父类中通常是不会出现同名成员变量,因为父类中只要定义了,子类直接继承过来使用即可,无需再定义。
<3>super
和 this : Java
先完成父类初始化,再完成子类初始化。因此子类会默认访问父类的空参构造方法。子类每一个构造方法中第一行都隐藏了一个super()
方法,以访问父类。如果父类没有设置空参构造,子类可以通过其空参构造中添加super(xxx,xxx)
访问父类有参构造方法或者通过添加this(xxx,xxx)
访问子类有参构造,进而达到访问父类有参构造方法的目的。
<4>方法重写(override)
:当子类有特征功能需要修改时,继承中可以使用同名方法,以覆盖父类方法。父类私有方法不可重写。子类重写父类,子类方法权限必须大于或等于父类方法权限,方可实现继承(定义子类目的是为了比父类更强大)。方法重写与返回值类型有关。方法重载(overload):
方法名一样,参数类型、数量不一样,与返回值类型无关。
<5>final
关键字可以修饰类、方法和变量。如果修饰类,类不能继承。修饰方法,方法不能重写。修饰变量,变量会变为常量,一般会和public static
一起使用,方便调用。final
修饰引用类型,引用类型的地址值不变,属性值却可以修改。final
初始化时机:显示初始化或在对象构造完毕前初始化值。
<5>多态: 父类引用指向子类对象。前提是有继承关系,有重写方法,有父类引用指向子类对象。可以使用instance of
判断前面的引用是否属于后面数据类型。
多态的特点:
(1)
成员变量:在编译时期:参考的是引用型变量所属的类中是否有调用的成员。(编译时不产生对象,只检查语法错误)运行时参考引用型变量所属的类中是否有调用的成员。即编译运行都看左边.
(2)
成员方法:编译时参考引用型类中是否有可以调用的方法,运行时看所属对象类是否有可调用的方法。即编译看左边,运行看右边。
(3)
静态方法编译时参考的引用型变量所属的类中是否有调用的成员。运行时也是参考引用型变量所属的类中是否有调用的成员。即编译运行都看左边。(因为静态方法,其实不属于对象,而是所属于该方法所在的类。用静态的方法引用是哪个类的引用调用的就是哪个类中的静态方法。)
/*
多态增加了程序的扩展性,但使用子类特有行为时,需要强转;
开发时很少在创建对象时,用父类引用创建子类对象,
一般直接创建子类对象,传参时使用多态,直接调用出子类重写的方法;
*/
class Demo {
public static void main(String[] args) {
//Animal a = new Cat();
show(new Cat());
show(new Dog());
}
public static void show(Animal a) {
if (a instanceof Cat) {
Cat c = (Cat)a; //强转为Cat,以调用Cat特有方法
c.catchMouse();
c.eat();
} else if (a instanceof Dog) {
Dog d = (Dog)a; //强转为Dog,以调用Dog特有方法
d.guardHouse();
d.eat();
} else {
a.eat();
}
}
}
class Animal {
public void eat() {
System.out.println("Animal eat");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("Cat eat fish");
}
public void catchMouse() {
System.out.println("Cat catch mouse");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("Dog eat meat");
}
public void guardHouse() {
System.out.println("dog guard house");
}
}
<6>abstract
抽象类不能访问子类特有属性和行为;抽象类中不一定有抽象方法,有抽象方法的一定是抽象类;抽象类不能直接实例化,如果要实例化可以使用子类实例化。抽象方法是父类强制子类做的事情 ,非抽象方法是子类继承父类的事。抽象类子类要么是抽象类,要么必须重写所有抽象方法。
抽象类成员特点:
(1)
成员变量可以是变量也可以是常量,abstract
不能修饰成员变量,因为变量是固定值,无法进行抽象。
(2)
抽象类有构造方法,用于子类访问数据的初始化。
(3)
成员方法可以用abstract
修饰,也可以不用。但如果使用abstract
修饰,子类必须重写该方法,或者把子类定义为abstract
类。
注意事宜:
(1)
可以定义没有抽象方法的抽象类,目的为不能直接创建该类对象。
(2)Abstract
关键字不能与static private final
共存;被static
修饰的方法可以直接通过类名调用,abstract修饰的方法没有方法体,通过类名调用抽象类没有意义;被private
修饰的成员方法不能继承,而被abstract
修饰,其成员方法必须重写或定义抽象子类;final
修饰的方法不能重写,被abstract
修饰的方法强制子类重写。