一、继承
1、子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承只是不能直接访问
2、无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类
中继承的成员变量,相当于在构造方法的第一行添加代码:super()的效果
3、使用继承必须满足逻辑关系:子类 is a 父类,即不能滥用继承
4、Java语言支持单继承不支持多继承,即一个子类只能有一个父类,但一个父类可以有多个
子类
对于super关键字:
1、可以访问父类的构造方法(通过super的构造方法的代码,必须写在子类构造方法的第一行)
2、可以访问父类的属性
3、可以访问父类的方法
二、方法重写
下面简单写一段关于继承 的代码:
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {}
public void play() {}
}
public class Student extends Person {
private int studentId;
public Student(int studentId) {
this.studentId = studentId;
}
public Student(String name, int age, int studentId) {
super(name, age);
this.studentId = studentId;
}
public void study() {}
}
public class Teacher extends Person {
private int teacherId;
public void teach() {}
}
public class Worker extends Person {
private double salary;
public void work() {}
}
注意:
权限修饰符
三、final关键字
//final修饰类不可以被继承,修饰方法不允许被子类重写
public class FinalDemo {
//final修饰的成员变量,必须在声明时赋值
//final修饰属性、变量,表示变量变常量,无法对其再进行赋值
final int age = 1;
public static void main(String[] args) {
//final修饰的局部变量,只能赋值一次(可以先声明后赋值)
//final int a = 2;
final int a;
a = 2;
}
}
四、抽象类
package com.java.zhangyutong.shape;
public class Shape {
private int x;
private int y;
public Shape() {}
public Shape(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void show() {
System.out.println("(x = " + x + ", y = " + y + ")");
}
}
package com.java.zhangyutong.shape;
public class Rect extends Shape {
private int length;
private int width;
public Rect() {}
public Rect(int length, int width) {
this.length = length;
this.width = width;
}
public Rect(int x, int y, int length, int width) {
super(x, y);
this.length = length;
this.width = width;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
@Override
public void show() {
System.out.println("矩形 (x = " + getX() + ", y = " + getY() + "), (length = " + getLength() + ", width = " + getWidth() + ")");
}
}
package com.java.zhangyutong.shape;
public class Circle extends Shape {
private int r;
public Circle() {}
public Circle(int r) {
this.r = r;
}
public Circle(int x, int y, int r) {
super(x, y);
this.r = r;
}
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
@Override
public void show() {
System.out.println("圆形 (x = " + getX() + ", y = " + getY() + "), (r = " + getR() + ")");
}
}
package com.java.zhangyutong.shape;
public class ShapeTest {
public static void printRec(Rect rect) {
rect.show();
}
public static void printCircle(Circle circle) {
circle.show();
}
public static void printShape(Shape shape) {
shape.show();
}
//static修饰的方法只能调用静态的方法
public static void main(String[] args) {
Shape shape = new Shape(3, 4);
shape.show();
shape = new Rect(4, 5, 6, 7);
shape.show();
shape = new Circle(5, 6, 7);
shape.show();
System.out.println("-----------------------");
printRec(new Rect(4, 5, 6, 7));
System.out.println("-----------------------");
printShape(new Shape(1, 2));
printShape(new Rect(4, 5, 6, 7));
printShape(new Circle(5, 6, 7));
}
}
对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段调用子类重写的版本。
对于父子类都有的静态方法来说,编译和运行阶段都调运父类版本。
引用数据类型之间的转换方式
1、自动类型转换:子类转换为父类
2、强制类型转换:父类转换为子类
package com.java.zhangyutong.account;
public abstract class Account {
private double balance;
public Account() {}
public Account(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public abstract double getInterest(double index, double time);
}
package com.java.zhangyutong.account;
public class FixedAccount extends Account {
public FixedAccount() {}
public FixedAccount(double balance) {
super(balance);
}
@Override
public double getInterest(double index, double time) {
return getBalance() * index * time;
}
public static void main(String[] args) {
Account account = new FixedAccount(1000);
System.out.println(account.getInterest(0.003, 1));
}
}
五、接口
String Info = ""; //public static final String Info = "";
void show(); //public abstract void show();
接口和抽象类的区别
1、定义抽象类的关键词是abstract class,而定义接口的关键字是interface。
2、继承抽象类的关键字是extends,而实现接口的关键字是implements。
3、继承抽象类支持单继承,而实现接口支持多实现。
4、抽象类中可以由构造方法,而接口中不可以有构造方法。
5、抽象类中可以有成员变量,而接口中只可以有常量。
6、抽象类中可以有成员方法,而接口中只可以有抽象方法。
7、抽象类中增加方法时子类可以不用重写,而接口中增加方法时实现类需要重写。
8、从jdk1.8开始增加新特性,接口中允许出现非抽象方法,但需要使用default关键字修饰。
package com.java.zhangyutong.run;
public interface Runner {
void runing();
}
package com.java.zhangyutong.run;
public interface Hunter extends Runner {
void hunt();
}
package com.java.zhangyutong.run;
public class Chinese implements Hunter {
@Override
public void hunt() {
System.out.println("抓到一只小白兔!!!");
}
@Override
public void runing() {
System.out.println("正在全力奔跑!!!");
}
}
package com.java.zhangyutong.run;
public class ChineseTest {
public static void main(String[] args) {
//接口类的引用指向实现类的对象
Runner runner = new Chinese();
runner.runing();
Hunter hunter = new Chinese();
hunter.hunt();
hunter.runing();
}
}