前言:
今天开始预习Java的继承知识,听了尚硅谷的课程,把其中一些概念和代码练习记录了一下,方便日后的回忆。(我的代码速度还是好慢)
话不多说,直接开始今天的正题.
1.Java继承的好处
① 减少了代码的冗余,提高了代码的复用性
②便于功能的拓展
③为以后多态性的使用,提供了前提
2.Java继承的格式
2.1格式
class A extends B{}
//A代表子类 B代表父类
2.2体现
一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有属性和方法.特别的,父类声明为private的属性或者方法,子类继承父类以后,仍然认为获取了父类中私有的结构.只是因为封装性的影响,使得子类不能直接调用父类的结构而已.
我们可以通过以下的代码来验证我们的说法:
public class Person {
String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("吃饭");
sleep();
}
private void sleep(){
System.out.println("睡觉");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//在Person类中,我们把方法sleep()定义为私有的,同时在公有的方法
//eat()中调用了这个方法
public class Student extends Person {
String major;
public Student(){
}
public Student(String name,int age,String major){
this.name = name;
setAge(age);
this.major = major;
}
public void study(){
System.out.println("学习");
}
public void show(){
System.out.println("name:" + name + ",age:" + getAge());
}
}
public class Test {
public static void main(String[] args) {
Student s = new Student();
s.sleep();
s.eat();
}
}
//若我们直接用子类调用sleep()方法,编译器会报错.
//The method sleep() from the type Person is not visible
//它告诉我们这个方法看不见,也就是没有权限去访问
这是控制台输出的结果,由输出可见,子类在调用父类方法的时候,也是获取了私有的方法的.
子类继承父类以后,还可以声明自己特有的属性或者方法,实现功能的拓展
3.继承的规则
3.1详细规则
①一个子类只能有一个父类
②一个父类可以派生出多个子类
③子类直接继承的父类称为:直接父类,间接继承的称为:间接父类
3.2父类
①如果我们没有显示的声明一个类的父类的话,则此类继承于java.lang.Object类
②所有的java类(除了object本身)都直接或间接的继承于java.lang.Object类
4.继承代码练习
4.1练习(1)
问题:
(1)定义一个ManKind类,包括
成员变量int sex和int salary
方法void manOrWoman():根据sex的值显示“man”(sex1)或者“woman”(sex0)
方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)
(2)定义类Kids继承ManKind,并包括
成员变量int yearsOld
方法printAge()打印yearsOld的值
定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法
public class ManKind {
private int sex;
private int salary;
//创建父类时候,一定要加上一个空的构造函数,否咋编译器报错
public ManKind() {
}
public ManKind(int sex, int salary) {
this.sex = sex;
this.salary = salary;
}
public void manOrWoman() {
if(sex == 1) {
System.out.println("man");
}
else if(sex == 0 ){
System.out.println("woman");
}
}
public void employeed() {
if(salary == 0) {
System.out.println("no job");
}
else if(salary == 1) {
System.out.println("job");
}
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
//因为权限的问题,get()和set()方法是必要的
}
public class Kids extends ManKind{
private int yearsOld;
public Kids() {
}
public Kids(int yearsOld) {
this.yearsOld = yearsOld;
}
public void printAge() {
System.out.println(yearsOld);
}
public int getYearsOld() {
return yearsOld;
}
public void setYearsOld(int yearsOld) {
this.yearsOld = yearsOld;
}
}
public class KidsTest {
public static void main(String[] args) {
Kids someKid = new Kids(12);
someKid.printAge();
someKid.setSalary(0);
someKid.setSex(1);
someKid.employeed();
someKid.manOrWoman();
}
}
4.2练习(2)
根据 下图实现类在 。在CylinderTest类 类建 中创建Cylinder 类的对象,设置圆柱的底面半径和高,并输出圆柱的体积
Circle (圆)
-radius :double
Circle(): 构造器,将radius属性初始化为1
+setRadius(double radius) : void
+getRadius(): double
+findArea():double 计算圆的面积
–
Cylinder (圆柱)
-length:double
Cylinder(): 构造器,将length属性初始化为1
+setLength(double length):void
+getLength():double
+findVolume() :double 计算圆柱体积
public class Circle {
private double radius;
public Circle() {
radius = 1.0;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea() {
return (Math.PI * radius * radius);
}
}
public class Cylinder extends Circle{
private double length;
public Cylinder() {
length = 1;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double findVolume() {
return Math.PI * getRadius() * getRadius() * getLength();
//因为权限的问题要去用get拿到
}
}
public class CylinderTest {
public static void main(String[] args) {
Cylinder c = new Cylinder();
c.setLength(10);
c.setRadius(10);
System.out.println(c.findArea());
System.out.println(c.findVolume());
}
}
手动分割线
从以上两个代码题中,我们可以得出:当用子类对象调用父类的方法时,我们一般通过get()和set()去调用,若是直接调用可能会出现问题,以下是我的错误例子.
public class Student1 extends Person1{
long number;
int math;
int english;
int computer;
public Student1(String name,char sex,int age,long n,int m,int e,int c) {
number = n;
math = m;
english = e;
computer = c;
}
public double aver() {
double sum = 0.0;
sum += math + english + computer;
return sum / 3;
}
public int max() {
int max = math > english ? math : english;
return (max > computer ? max : computer);
}
public int min() {
int min = math < english ? math : english;
return (min < computer ? min : computer);
}
public String toString() {
return "姓名:" + name + " 性别:" + sex + " 年龄:" + age + "学号:" + number
+ "平均成绩:" + aver() + " 最高分:" + max() + " 最低分:" + min();
}
}
public class Person1 {
String name;
char sex;
int age;
public Person1() {
}
public Person1(String name,char sex,int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "姓名:" + name + "性别:" + sex + "年龄:" + age ;
}
}
Student1 s = new Student1("yzz", '女', 20, 10001, 90, 100, 120);
System.out.println(s.toString());
这么多错误代码,我是没有耐心看的,简单的说一下我的问题吧.
在继承的子类中,我为构造函数传参,这个过程子类调用了父类的默认构造函数,所以最后的输出结果中 “姓名:null” ,而为了避免出现此类错误,我们通常用get()和set()的方法来解决问题.
结束语:
只有比别人更早更勤奋地努力,才能尝到成功的滋味.