继承
package com.atguigu.exer;
public class People{
String name = new String();
int age;
public People() {
}
public People(String name,int age) {
this();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("im eating");
}
}
package com.atguigu.exer;
public class Student extends People{
String major;
public Student() {
}
}
package com.atguigu.exer;
public class Text {
public static void main(String[] args) {
People p = new People();
p.age = 99;
p.name = "扎根";
Student s = new Student();
s.name = "wse";
System.out.println(s.name);//wse
s.eat();//im eating
}
}
继承的格式:
class A extends B{}
A:子类、派生类、subclass
B:父类、超类、基类
体现:一旦子类A继承父类B,A获取了父类B中声明的结构
子类继承父以后,还能声明自己特有的属性或方法,实现功能的拓展
一个类只能有一个父类
如果没有显式声明一个父类的化,则此类继承于java.lang.Object类
所有java类除Object都直接或间接继承Object类
例子:
package com.atguigu.CylinderCul;
public class Circle {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public Circle() {
this.radius = 1;//初始化半径为1
}
public double findArea() {
return this.radius*this.radius*Math.PI;
}
}
package com.atguigu.CylinderCul;
public class Cylinder extends Circle{
//圆柱
private double length;
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double findVolume() {
return this.findArea() * this.length;
}
}
package com.atguigu.CylinderCul;
public class Test {
public static void main(String[] args) {
Cylinder cylinder = new Cylinder();
cylinder.setRadius(3);
cylinder.setLength(5);
double v = cylinder.findVolume();
System.out.println(v);//141.3716694115407
}
}
重写
子类继承父类后,可以对父类同名同参数的方法,进行覆盖操作
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法,子类重写的方法名和父类被重写的方法名和形参列表相同
子类重写的方法的权限修饰符不小于父类被重写的方法
声明方法:
权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{方法体}
特殊情况:子类不能声明父类声明为private权限的方法
父类被重写的方法值类型为void,子类也只能是void
父类被重写的方法为A类型,子类是A类或A的子类
父类……为基本数据类型,则子类……也为相同基本数据类型
子类重写的方法抛出的异常类型大小不大于父类被重写的方法抛出的异常
super
可以在子类中调用super.属性或super.方法使用父类的属性或方法,但通常省略;
特殊情况,当子类和父类定义同名属性,要用父类属性,就要用super
package com.atguigu.exer;
public class Person{
String name = new String();
int age;
int id = 10086;//身份证id
public Person() {
}
public Person(String name,int age) {
this();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("im eating");
}
}
package com.atguigu.exer;
public class Student extends Person{
String major;
int id = 1001;//学生证号码
public Student() {
}
@Override
public void eat() {
super.eat();
System.out.println("im eating fish");
}
public void study(){
System.out.println("学生在学习");
}
public void show() {
System.out.println("name=" + name + ",age=" + age + ",id=" + id);
System.out.println(super.id);
}
}
package com.atguigu.exer;
public class SuperText {
public static void main(String[] args) {
Student s = new Student();
s.show();
}
}
代码中,id属性子类(Student)和父类(Person)都存在,在子类中,不加this或super时,默认为子类的id,加super则为父类的id
super调用构造器
我们可以在子类的构造器中显式的使用”super(形参列表)"的方式,调用父类中声明的指定构造器;
我们在类的构造器中,this(形参列表)或super(形参列表)只能二选一,不能同时出现;
在构造器的首行,没有显式声明this(形参列表)或super(形参列表),默认用super
public Person() {
System.out.println("我是你爸爸");
}
public Student() {
}
Student s = new Student();//打印”我是你爸爸“
在类的多个构造器中,至少有一个类的构造器中使用了”super(形参列表)",调用父类的构造器(前提是子类)
明确:创造子类对象时,调用了父类的构造器,但至始至终就创建过一个对象,即为new的子类对象
例题
package com.atuguigu.java1;
//三角形的类
public class Account{
private int id;
private double balance;
private double annuallnterestRate;//年利润
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnuallnterestRate() {
return annuallnterestRate;
}
public void setAnnuallnterestRate(double annuallnterestRate) {
this.annuallnterestRate = annuallnterestRate;
}
public Account(int id,double balance,double annuallnterestRate) {
this.id = id;
this.balance = balance;
this.annuallnterestRate = annuallnterestRate;
}
public void withdraw(double amount) {
//取款方法
if(amount <= this.getBalance()) {
this.balance -= amount;
System.out.println("您的账户余额为:" + this.getBalance() + "元");
}
}
public void deposit(double amount) {
//存款方法
this.balance += amount;
}
}
package com.atuguigu.java1;
public class CheckAccount extends Account{
//可透支的账户
double overdraft = 5000;
public CheckAccount(int id, double balance, double annuallnterestRate) {
super(id, balance, annuallnterestRate);
// TODO Auto-generated constructor stub
}
@Override
public void withdraw(double amount) {
// TODO Auto-generated method stub
if(amount < this.getBalance()) {
super.withdraw(amount);
}else {
if(amount - this.getBalance() <= this.overdraft) {
//修改可透支额度
this.overdraft -= (amount - this.getBalance());
//透支,存款为0
this.setBalance(0);
System.out.println("您的账户余额为:" + this.getBalance() + "元");
System.out.println("您可透支的金额为:" + this.overdraft);
}else {
System.out.println("取钱失败,超出预支金额" + (amount - this.getBalance() -5000));
}
}
}
}
package com.atuguigu.java1;
public class MainFunction {
public static void main(String[] args) {
/*
Account ac = new Account(1221, 22000, 0.43);
ac.deposit(5000);
ac.withdraw(9000);
*/
CheckAccount ad = new CheckAccount(1221, 1000, 0.45);
ad.withdraw(3000);
ad.deposit(901000);
System.out.println(ad.getBalance());
}
}
结果:
多态
对象的多态性:父类的引用指向子类的对象
多态的使用:当调用子父类同名同参数的方法时,实际执行的是 子类重写父类的方法——虚拟方法调用
有了对象的多态性以后,在编译器,只能调用父类中声明的方法,但运行期,实际执行的是子类重写父类的方法
总结:编译看左边,运行看右边
package com.atguigu.exer;
public class Person{
String name = new String();
int age;
int id = 10086;//身份证id
public Person() {
}
public Person(String name,int age) {
this();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("im eating");
}
}
package com.atguigu.exer;
public class Student extends Person{
String major;
int id = 1001;//学生证号码
public Student() {
}
@Override
public void eat() {
super.eat();
System.out.println("im eating fish");
}
public void study(){
System.out.println("学生在学习");
}
public void show() {
System.out.println("name=" + name + ",age=" + age + ",id=" + id);
System.out.println(super.id);
}
}
package com.atguigu.exer;
public class SuperText {
public static void main(String[] args) {
Person s = new Student();
//s.show(); //报错:因为Person类中没有show方法(虽然Student)中有
}
}
个人理解:
注意:多态性不适用于属性(编译和运行都看左边)
public class Student extends Person{
String major;
int id = 1001;//学生证号码
}
package com.atguigu.exer;
public class Person{
String name = new String();
int age;
int id = 10086;//身份证id
}
package com.atguigu.exer;
public class SuperText {
public static void main(String[] args) {
Person s = new Student();
System.out.println(s.id);//10086,答案是父类的id
}
}
有对象多态性后,内存实际上加载了子类特有的属性方法,由于声明的是父类类型,导致编译时,只能调用父类的属性方法,子类特有的属性和方法不能调用。
如何才能调用子类型特有的属性和方法?强转(向下转型)
package com.atguigu.exer;
public class Person{
String name = new String();
int age;
int id = 10086;//身份证id
public Person() {
}
public Person(String name,int age) {
this();
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("im eating");
}
}
package com.atguigu.exer;
public class Student extends Person{
String major;
int id = 1001;//学生证号码
public Student() {
}
@Override
public void eat() {
super.eat();
System.out.println("im eating fish");
}
public void show() {
System.out.println("name=" + name + ",age=" + age + ",id=" + id);
System.out.println(super.id);
}
}
package com.atguigu.exer;
public class Text {
public static void main(String[] args) {
Person s = new Student();
System.out.println(s.id);//10086
//s.show();//不能调用
Student s2 = (Student)s;
s2.show();//可以调用
System.out.println(s2.toString());
System.out.println(s.toString());//两地址相同
}
}
instanceof
a instanceof A:判断对象a是否是类A的实例,如果是,返回true,否则,false
System.out.println(s2 instanceof Student);//true
使用情境:使用向下转型前做一个判断,避免ClassCastException异常
例题
package com.atguigu.CylinderCul;
public class GeometricObject {
private String color;
private double weight;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
public double findArea() {
// TODO Auto-generated method stub
return 0.0;
}
}
package com.atguigu.CylinderCul;
public class Circle extends GeometricObject{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public Circle(String color, double weight) {
super(color, weight);
// TODO Auto-generated constructor stub
}
public Circle(String color, double weight, double radius) {
super(color, weight);
this.radius = radius;
}
public double findArea() {
return this.radius*this.radius*Math.PI;
}
}
package com.atguigu.CylinderCul;
public class Myrectangle extends GeometricObject{
private double width;
private double height;
public Myrectangle(String color, double weight) {
super(color, weight);
// TODO Auto-generated constructor stub
}
public Myrectangle(String color,double weight,double width,double height) {
super(color, weight);
this.width = width;
this.height = height;
}
public double findArea() {
return width*height;
}
}
package com.atguigu.CylinderCul;
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
GeometricObject o1 = new Circle("black", 1.0, 5);
GeometricObject o2 = new Myrectangle("white", 1.0, 6, 7);
System.out.println(test.equalArea(o1,o2));
}
public void displayGeometricObject(GeometricObject o) {
System.out.println("面积为:" + o.findArea());
}
public boolean equalArea(GeometricObject o1,GeometricObject o2) {
return o1.findArea() == o2.findArea();
}
}
结果为false