继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
类似的两个类重复变量和方法
class Penguin {
private String name;
private int id;
public Penguin(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
class Mouse {
private String name;
private int id;
public Mouse(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
我们发现两个类的方法和变量重复于是我们定义一个公共类
- protected修饰符: 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
class Animal {
// 建议公共类中的修饰符使用protected
protected String name;
protected int id;
protected Animal(String myName, int myid) {
this.name = myName;
this.id = myid;
}
protected void eat(){
System.out.println(name+"正在吃");
}
protected void sleep(){
System.out.println(name+"正在睡");
}
protected void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
继承的语法
class 父类 {}
class 子类 extends 父类 { }
企鹅老鼠类继承动物类
class Penguin extends Animal {
// 构造方法直接赋值
Penguin(String myName, int myid) {
super(myName, myid);
}
}
class Mouse extends Animal {
// 构造方法直接赋值
Mouse(String myName, int myid) {
super(myName, myid);
}
}
使用
public static void main(String[] args) {
Mouse m1 = new Mouse("米老鼠", 124);
System.out.println(m1.name);
m1.introduction();
m1.eat();
m1.sleep();
Penguin p1 = new Penguin("QQ", 666);
System.out.println(p1.name);
p1.introduction();
p1.eat();
p1.sleep();
}
/**
* 米老鼠
* 大家好!我是124号米老鼠.
* 米老鼠正在吃
* 米老鼠正在睡
* QQ
* 大家好!我是666号QQ.
* QQ正在吃
* QQ正在睡
*/
super和this
- super简单理解就是当前引用的父类
- this就是当前类
class Dog extends Animal {
Dog(String myName, int myid) {
super(myName, myid);
}
public void eat() {
System.out.println("我是Dog类自带的方法!");
}
public void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
Dog d = new Dog("狗子", 12);
d.eatTest();
// 我是Dog类自带的方法!
// 狗子正在吃
切记
- 子类不能继承父类private修饰符修饰的变量和方法,只能继承public protected和默认修饰符修饰的变量和方法
子类对父类方法的重写
- 父类的方法
class Father {
protected int rewrite() {
return 1;
}
}
- 修饰符可以扩大不能缩小
int rewrite() {
return 1;
}
报错 Cannot reduce the visibility of the inherited method from Father
final protected int rewrite() {
return 1;
}
正确
- 子类继承自父类的方法返回值类型必选相同
int rewrite() {
return 1;
}
报错 Duplicate method rewrite() in type Dog
- 正确重写方式
protected int rewrite() {
return 2;
}
构造方法
- 子类调用父类中构造方法,无参构造方法可以使用super()直接调用。
class Animal {
protected String name;
protected Animal() {
this.name = "无参构造函数";
}
}
class Child extends Animal {
public Child() {
super();
}
}
// super() 调用无参构造函数,必须写在第一行。
Child c1 = new Child();
System.out.println(c1.name);
// 打印=> 无参构造函数
注意 super()必须放在第一行,而且普通方法中无法使用。
补充一个快捷的测试打印方法。
- 鼠标右键 -> Source -> Generate toString...
class Animal {
// 右键 -> Source -> Generate toString... 方便测试。
@Override
public String toString() {
return "Animal [name=" + name + ", id=" + id + "]";
}
// protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
protected String name;
protected int id;
}
Animal a1 = new Animal("大能猫", 123);
System.out.println(a1);
// => Animal [name=大能猫, id=123]
总结
修饰符
1、类成员的修饰符:public 默认 protected private 四种访问修饰符和 final static配合使用。
{
String name; // default,默认修饰符
private int a;// 显示指定使用private修饰
protected int b;// 显示指定使用protected修饰
public int c;// 显示指定使用public修饰
public static int d;
public static final int e; // 报错
public static final int e = 1;// final 命名时必须赋值
}
2、类方法的修饰符和类成员一样。
{
void test(){};
private void test(){};
protected void test(){};
public void test(){};
public staticvoid test(){};
public static final void test(){};
}
3、类的修饰符
{
class A {};
public class B {};
public final C {}; // 终极类不能被继承
}
抽象类和抽象方法的继承
抽象类和方法可以让你少写很多代码,抽象方法不用定义主体。
- 使用abstract修饰的类为抽象类
public abstract class Pet {}
- 使用abstract修饰的方法可以没有方法主题,称为抽象类。
public abstract void print()
抽象方法只能在抽象类中,但是抽象类可以没有抽象方法。
public abstract class Pet {
public abstract void print();
}
抽象类可以继承普通类,普通类也可以继承抽象类,抽象类也可以继承抽象类。
多继承(implements )
- 多继承的类只能通过接口来实现
- 接口- interface 作为关键字定义
- 接口中只能有抽象方法 ,不能有具体方法,而且方法只能使用public abstract来修饰,省略则默认添加
- 可以定义成员变量,但是需要使用public static final修饰,省略则默认添加
interface A {
int height = 180;
public abstract void test1();
public abstract void test2();
public void test3();
void test4(); // 如果不指定默认为有public abstract修饰
}
interface B {
static int width = 200;
public void test5();
}
/** ----子类继承接口 -------------------------------------------------------------------- */
class C implements A, B {
// 鼠标右键 source Override/……
@Override
public void test1() {
System.out.println("打印方法1");
}
@Override
public void test2() {
}
@Override
public void test3() {
}
@Override
public void test4() {
}
@Override
public void test5() {
System.out.println("打印方法5");
}
}
public class MultipleInheritance {
public static void main(String[] args) {
C c1 = new C();
c1.test1();
c1.test5();
System.out.println("长:" + c1.height + ",宽:" + c1.width);
}
}
// 结果
// 打印方法1
// 打印方法5
// 长:180,宽:200
接口和类的区别
- 抽象类中可以有非抽象方法,接口中只能有抽象方法。
- 抽象类中的方法可是使用各种修饰符,但是接口中只能使用public abstract来修饰
- 抽象类中的属性可以有多重修饰符,但是接口中属性必须使用public static final修饰
多态,向上转型,向下转型。
- 当声明类型和实际类型不一样的时候,子类重写了父类的方法,在调用这个方法时,调用的实际类型中的方法。
interface A {
void test1() {}
}
interface B {
void test5() {}
}
class C implements A,B {
}
A c1 = new C();
c1.test1();
/** c1.test5();// 报错,因为用A声明的类型只能使用A里面的方法*/
((B) c1).test5(); /** 正确方式“向下转型,也就是强转” */
子类对父类的属性访问
- 不能通过super.属性名来访问父类属性。
- 推荐使用父类.属性名的方式访问。
class Father {
String name = "F";
}
class Child extends Father{
void test() {
System.out.println(super.height); 报错
System.out.println(Father.height); 正确
}
}
上一章 | 目录 | 下一章 |
---|