一.代码块
代码块是一种常见的代码形式。他用大括号“{}”将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块.而代码块又分为四种.
1.局部代码块
在方法中用一对大括号括起来代码.局部代码块限定了局部变量的声明周期.
public static void main(String[] args) {
// 局部代码块
{
System.out.println("局部代码块");
}
}
2.构造代码块
在类中 方法外用一对大括号括起来代码.在你创建对象的时候,如果你的类中有构造代码块的话,系统会自动帮你优先调用构造代码块,然后在调用构造方法.如果类的对象中有相同的功能要实现的话可以使用构造代码块调用.
class A{
int a;
//构造代码块
{
}
// 方法
public void sayHi(){
}
}
3.静态代码块 – 使用static修饰
静态代码块也是在类中方法外用一对大括号括起来代码.静态代码块只加载一次,而且是根据类的加载而加载.根据静态代码块的特点可以使用静态代码块的原理来加载驱动,
class A{
int num;
//静态代码块
static {
}
public void sayHi(){
}
}
4.同步代码块 — 多线程
二.继承的定义
继承是指一个类直接使用另一类的属性和方法,连接了两个类之间的关系,通常称为父子关系 – 父类与子类,子类调用父类的属性和方法.
1.继承的方法
一般使用extends关键字来使用继承:
class 子类 extends 父类{
}
代码举例:
创建一个动物类:
// 类中不可以定义类
// 定义一个animal父类
class Animal{
string name;
string color;
public void sayHi(){
System.out.println(name + "---" + color);
}
}
//定义一个Cat子类
class Cat extends Animal{
}
//定义一个Dog子类
class Dog extends Animal{
}
public class Demo01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "黑猫";
cat.color = "橘黄";
cat.sayHi();
}
}
这里创建一个Animal父类,里面定义了两个成员变量–name和color,也定义了两个子类–Cat和Dog,而Cat可以调用Animal里的变量.同样的,Dog也可以调用,这就可以看出Cat类和Dog类是Animal的子类.这样就减少了许多的重复代码,实际开发的过程中,可以节省工作量.
2.继承的特点
a.可以把子类中的同样的属性和方法提取出来,写成一个父类.
b.就可以减少大量重复的代码,进而减少你的工作量;
3.继承的使用选择
只有子类是父类的一个分支的时候才可以使用继承,就是说要符合逻辑,例如:父类是fruit类,子类可以是apple类,banana类等属于fruit的一个对象的时候就可以使用继承.但是如果你定义父类为apple类,子类为banana类的话,这样就不可以,apple和banana属于同一子类,所以不能使用继承.
但是有时候父类中如果有子类不想继承的属性或者方法的话,就不能使用继承,所以使用继承还是不使用继承都是根据实际情况而定的.
三.java中的继承
Java继承是面向对象的最显著的一个特征。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和方法,并能扩展新的能力。
1.java继承的特点
a.java允许单继承,不允许多继承,但是可以使用借口实现和多继承相同的功能;
b.java允许多层继承,就是说c类继承b类,b类继承a类,那么c类也能继承a类,下面举例说明:
//定义父类A
class A{
int num;
public void sayHi(){
System.out.println(num);
}
}
//定义子类B
class B extends A{
}
//定义子类C
class C extends B{
}
public class Demo02 {
public static void main(String[] args) {
C c = new C();
c.num = 5;
c.sayHi();
}
}
由此可以看出,java是可以实现多重继承的,C类是可以继承到A类的.
事实上,A类也是继承了系统的一个类 – Object类.如果一个类明确没写继承哪个类,那么实际上就是继承了Object类.
Object又被称为基类,是java中最顶端的类.
2.类的选择
如果你想得到类中的共有的属性和方法,就应该使用继承中最顶端的那个类;
如果你想得到类中的特有的属性和方法,就应该使用继承中最某段的那个类.
四.继承的一些问题
A.两个类的继承
1.类继承中的构造方法
首先注意构造方法是不能继承的,父类和子类的构造方法要分别定义.其中在子类中,不管子类是有参还是无参的构造方法,子类都会默认调用父类的无参构造(使用super();).
举例说明:
//定义一个父类
class Father{
String name;
public Father() {
System.out.println("我是爸爸的无参构造方法");
}
public Father(String name) {
System.out.println("我是爸爸的有参构造方法");
}
public void sayHi() {
System.out.println(name);
}
}
//定义一个子类
class Son extends Father{
public Son() {
// 如果你没有调用父类的构造方法
// 那么系统会在这里帮你调用一下父类无参构造方法
super();// 调用父类的无参构造方法
System.out.println("我是儿子的无参的构造方法");
}
public Son(String name) {
// 不管有参还是无参的构造方法
// 只要你没有调用父类的构造方法
// 系统都会帮你调用,保证继承的完整性
super();// 调用父类的无参构造方法
System.out.println("我是儿子的有参的构造方法");
}
}
public class Demo03 {
public static void main(String[] args) {
Son son = new Son();
son.sayHi();
System.out.println("------------------");
Son son2 = new Son("张三");
son2.sayHi();
}
}
2.两个类的继承关系
父类如果没有无参的构造方法(说明有有参的构造方法),那么该如何去屑子类的构造方法呢?
举例说明:
..定义父类Car
class Car{
String name;
// public Car() {
// System.out.println("Car我是无参数的构造方法");
// }
public Car(String name) {
this.name = name;
System.out.println("Car我是有参数的构造方法");
}
}
// 定义子类Audi
class Audi extends Car{
public Audi() {
// 只要你在构造方法的第一行调用构造方法
// 这时 系统将不再给你指定调用默认的无参构造方法
super("A8");
System.out.println("Audi我是无参数的构造方法");
}
public Audi(String name) {
// 你不写调用父类构造 默认系统给你调用无参构造
// 你可以制定一个构造方法去调用
super(name);// 调用了父类 有参的构造方法
System.out.println("Audi我是有参数的构造方法");
}
public void sayHi() {
System.out.println(name);
}
}
public class Demo04 {
public static void main(String[] args) {
Audi a = new Audi("R8");
a.sayHi();
System.out.println("-------------");
Audi b = new Audi();
b.sayHi();
}
}
由此可以看出,如果你不写调用父类构造,系统会默认给你调用无参构造只要你在子类的构造方法的第一行调用父类的有参构造方法后,那么系统就不会自动给你默认给你调用父类的无参构造方法.同时你也可以通过super();调用指定父类的有参构造方法.
B.继承的子类与父类的问题
1.继承时子类与父类有相同名字的成员变量
举例说明:
//定义父类Fruit
class Fruit{
int num1 = 10;
int num2 = 20;
}
//定义子类Apple
class Apple extends Fruit{
int num2 = 30;
public void print() {
System.out.println(this.num1);
System.out.println(this.num2);
System.out.println(super.num2);
}
}
public class Demo05 {
public static void main(String[] args) {
Apple apple = new Apple();
apple.print();
}
}
子类通过this和super调用父类和子类的成员变量,那么this和super有什么区别呢?
1.this和super的区别
this在类中代表的是本类的成员变量,是this所在类的对象.
super在类中代表的是父类中的对象,在子类中也会优先在父类中找父类的对象.
2.this.属性和super.属性
this.属性:可以调用当前类的属性.优先找当前类的,如果本类中找不到,那么就会去父类中寻找.this.属性遵循就近原则.
super.属性:调用父类的属性
3.this();和super();
this();调用本类的构造方法.
super();调用父类的构造方法.
2.继承时父类和子类有相同名字的成员方法
举例说明:
class Cup{
public void Print() {
System.out.println("我是Cup");
}
}
class GlassCup extends Cup{
public void print() {
// Override(重写) 和 Overload(重载) 有什么区别?
// 方法重载是参数不一样 但是方法名一样
// 方法重写是当父类和子类的方法完全一致时
super.Print();
System.out.println("我是玻璃杯");
}
}
public class Demo06 {
public static void main(String[] args) {
GlassCup G = new GlassCup();
G.print();
}
}
可以看出,父类和子类的方法名是一样的,这时从子类中创建一个对象,调用print方法,发现会打出父类和子类分别定义的两个句话,这就是方法的重写–当父类和子类方法名完全一致时叫做方法的重写.但是可以使用super.方法调用父类的方法.
重写的应用场景:
当子类的方法相对于父类的方法有了升级,这时你可以使用方法的重写.
五.final关键字
只需要记住三个修饰的作用就好了:
1.修饰类:不能被继承
2.修饰变量:不能被修改
3.修饰方法:不能被重写