继承
- 将多个类中共有的属性,方法剥离出来单独创建一个共有类,当需要使用共有的属性与方法时,就可以通过继承(extends)来调用共有的属性与方法。
- 通过"
class A extends B
" 来实现类的继承(子类:A 父类(或基类SuperClass):B) - 子类继承父类,父类中声明的属性,方法,子类就可以获取得到(父类中的私有方法,属性,子类可以获得,但由于封装性的设计,子类不可以直接调用)
- 子类除了通过继承父类的属性与方法,还可以自己定义特有的成分
- 在继承中,子类是父类功能的"扩展",即子类不是父类的子集。
- Java类的继承只支持单继承(一个子类只能继承一个父类,一个父类可以有多个子类)
- 子类父类是相对的概念(子类可以用直接父类(1个),间接父类(0~多个))
事例
//这些类可以写在不同的文件里
public class Test3 { public static void main(String[] args) {Student s = new Student("学生",17);s.info();Worker w = new Worker("打工人",32);w.info();}
}class Student extends Person{ // private String name; // private int age; private String school = "明德完小"; public Student(String name,int age){ // this.name = name; // this.age = age; this.setAge(age); this.setName(name); }// public void setName(String name){ // this.name = name; // }// public void setAge(int age){ // this.age = age; // }// public String getName( ){ // return name; // }// public String getAame( ){ // return age; // }public String getSchool( ){ return school; }// public void info(){ // System.out.println("name: " + this.name + "age: " + this.age); // }}class Worker extends Person{//继承Person类// private String name;// private int age;public Worker(String name,int age){// this.name = name;// this.age = age;this.setAge(age);this.setName(name);}// public void setName(String name){// this.name = name;// }// public void setAge(int age){// this.age = age;// }// public String getName( ){// return name;// }// public String getAame( ){// return age;// }// public void info(){// System.out.println("name: " + this.name + "age: " + this.age);// }
}
class Person{//将上面相同的部分,合成一个类private String name;private int age;public void setName(String name){this.name = name;}public void setAge(int age){this.age = age;}public String getName( ){return name;}public String getAame( ){return age;}public void info(){System.out.println("name: " + this.name + " " + "age: " + this.age);}}
练习
题一
// 父类
class ManKind{private int salary; private int sex;public int getSex() {return sex;}public int getSalary() {return salary;} public void setSex(int sex) {this.sex = sex;} public void setSalary(int salary){this.salary = salary;}public void manOrWorman(){if(sex == 1){System.out.println("man");}if(sex == 0){System.out.println("woman");}}public void employeed(){if(salary == 0){System.out.println("no job");}if(sex != 0){System.out.println("job");}}
}
//子类class Kids extends ManKind{private int yearOld;public void yearOld(int yearOld){this.yearOld = yearOld;}public void printAge(){System.out.println("yearOld: " + yearOld);}
}public class Test3{public static void main(String[] args) {Kids somekid = new Kids();somekid.setSalary(0);somekid.setSex(0);somekid.yearOld(14);somekid.employeed();somekid.manOrWorman();somekid.printAge();}
}
题二
//这些类可以写在不同的文件里
public class Person{ private String name;private int age;private char sex;public void setName(String name){this.name = name;}public void setAge(int age){this.age = age;}public void setSex(char sex){this.sex = sex;}public String getName( ){return name;}public int getAge( ){return age;}public char getSex(){return sex;}public Person(String name,char sex,int age){this.age = age;this.name = name;this .sex = sex;}public String toString(){return 0;}}class Student extends Person{private long number;private int math;private int english;private int computer;public Student(String n,char s,int a,long k,int m,int e,int c){// this.setName(n);// this.setAge(a);// this.setSex(s);super(n, s, e);//调用父类的构造器this.number = k;this.computer = c;this.math = m;this.english = e; }public double aver(){return 0;}public int max(){return 0;}public String toString(){return 0;}
}
重写
修饰符 返回值类型 方法名(参数列表){}
前提:有子类继承父类
对父类同名方法的重写(覆盖),即子类继承父类后,父类的方法不适合子类,则可以选择重写来对父类的方法进行覆盖。
注意区分重写与重载的区别
重写规则
- 子类的方法的"返回值 方法名(参数列表)" 与父类的方法一致
- 子类的方法的修饰符不能小于父类方法的修饰符
- 若父类方法抛异常,那么子类方法抛的异常类型不能大于父类的异常类型
- 子父类的方法必须同为static或非static的
事例
public class Person{ private String name;private int age;private char sex;public void setName(String name){this.name = name;}public void setAge(int age){this.age = age;}public void setSex(char sex){this.sex = sex;}public String getName( ){return name;}public int getAge( ){return age;}public char getSex(){return sex;}// public Person(String name,char sex,int age){// this.age = age;// this.name = name;// this .sex = sex;// }public void sleep(){System.out.println("我是人,我要要睡觉!");}
}class Student extends Person{ // public Student(String name, char sex, int age) {// super(name, sex, age);// //TODO Auto-generated constructor stub// }//对父类sleep()方法重写public void sleep(){System.out.println("我是学生,我要睡觉!");}}
多态
一个事务的多种表达形态
- 表现:
方法的重载和重写。
子类对象的多态性–直接应用在抽象类和接口上。 - Java引用变量有两个类型:编译时类型(”看左边“由声明该变量时使用的类型决定)和运行时类型(”看右边“由实际赋给该变量的对象决定)
- 虚拟方法调用:通过父类的引用指向子类的对象实体,调用方法时,实际执行的是子类重写父类的方法
- 子类对象的多态性使用的前提:
有类的继承
有子类对父类方法的重写
子类对象的多态性并不适用于属性
instanceof
(判断某个对象是否属于莫类的实例)
格式:对象a instanceof 类A
判断对象a是否为类A的实例,是就返回true,不是就返回false;
如果对象a是类A的一个实例,那对象a一定是类A的父类的实例
事例
//父类
class Person{ private int age;private String name;public Person(){super();}public Person(String name,int age){super();this.age = age;this.name =name;}public int getName() {return name;}public void setName(String name) {this.name = name;} public int getAge() {return age;}public void setAge(int age) {this.age = age;} public void ren(){System.out.println("我是人类");}
}
//子类
class Man extends Person{private boolean smoking;public Man(){super();}public Man(boolean smoking){super();this.smoking = smoking;}public boolean getSmoking() {return smoking;}public void setSmoking(boolean smoking) {this.smoking = smoking;} public void ren(){System.out.println("我是男人");}public void game(){System.out.println("我要打游戏");}
}class Woman extends Person{private boolean beauty;public Woman(){super();}public Woman(boolean beauty){super();this.beauty = beauty;}public boolean getBeauty() {return beauty;}public void setBeauty(boolean beauty) {this.beauty = beauty;} public void ren(){System.out.println("我是女人");}public void shopping(){System.out.println("我要购物");}
}
//测试
public class Test4{ public static void main(String[] args) {//子类对象的多态性: 父类的引用指向子类的对象Person p = new Man();//向上转型(子-->父)//虚拟方法调用p.ren();//Man的方法// p.game();此时的对象为Person类型,Person中无game()方法Person p1 = new Woman();p1.ren();//Woman的方法Woman w = (Woman)p1;//向下转型(使用强转符:父--->子)w.shopping();//instanceof判断某个对象是否属于某类的实例if(p instanceof Woman){Woman w1 = (Woman)p;w1.shopping();}if(p instanceof Man){Man m1 = (Man)p;m1.game();}if(p instanceof Person){System.out.println("carry!");}}
}
案例:
//父类
class Person{ private int age;private String name;public Person(){super();}public Person(String name,int age){super();this.age = age;this.name =name;}public int getName() {return name;}public void setName(String name) {this.name = name;} public int getAge() {return age;}public void setAge(int age) {this.age = age;} public void ren(){System.out.println("我是人类");}
}
//子类
class Man extends Person{ private boolean smoking;public Man(){super();}public Man(boolean smoking){super();this.smoking = smoking;}public boolean getSmoking() {return smoking;}public void setSmoking(boolean smoking) {this.smoking = smoking;} public void ren(){System.out.println("我是男人");}public void game(){System.out.println("我要打游戏");}
}class Woman extends Person{private boolean beauty;public Woman(){super();}public Woman(boolean beauty){super();this.beauty = beauty;}public boolean getBeauty() {return beauty;}public void setBeauty(boolean beauty) {this.beauty = beauty;} public void ren(){System.out.println("我是女人");}public void shopping(){System.out.println("我要购物");}
}
//测试
public class Test4{public static void main(String[] args) {Test4 t = new Test4();t.fun(new Person());t.fun(new Man());}public void fun(Person p){p.ren();}
}
练习
题一
题二
class GeometricObject{ private String color;private double weight;public GeometricObject(String color,double weight){this.color = color;this.weight = weight;}public void setColor(String color){this.color = color;}public String getColor(){return color;}public void setWeight(double weight){this.weight = weight;}public double getWeight(){return weight;}public double findArea(){return 0.0;}}
//子类
class Circle extends GeometricObject{private double radius;public Circle(double radius,String color,double weight){super(color,weight);this.radius = radius;}public double findArea(){return Math.PI * radius *radius;}public void setRadius(double radius){this.radius = radius;}public double getRadius(){return radius;}
}class MyRectangle extends GeometricObject{private double width;private double height;public MyRectangle(double width,double height,String color,double weight){super(color, weight);this.width = width;this.height = height;}public void setWidth(double width){this.width = width;}public double getWidth(){return width;}public void setHeight(double height){this.height = height;}public double getHeight(){return height;}public double findArea(){return height * width;}
}//测试
public class Test2{ public static void main(String[] args) {Test2 t = new Test2();Circle c = new Circle(2.3, "green", 1.0);MyRectangle m = new MyRectangle(2.3, 3.0, "green", 2.0);t.displayGeometricObject(c);t.displayGeometricObject(m);boolean a = t.Area(c, m);System.out.println(a);}public boolean Area(GeometricObject s1,GeometricObject s2){return s1.findArea() == s2.findArea();}public void displayGeometricObject(GeometricObject s){System.out.println("面积" + s.findArea());}
}
3. 其他关键字
this
- this表示当前对象,可以调用类的属性,方法和构造器
public class Test3 { public static void main(String[] args) {Person p = new Person(); //Person()即为空参的构造器p.setAge(10);p.info();p.setName("小王");p.info();}
}class Person{private String name;private int age;//构造器public Person(){}public Person(String name){this.name = n;}public Person(String name,int age){this(name);//显示调用当前类的重载的指定的构造器this.age = a;}//方法public String getName(){return name;}public String getAge(){return age;}public void setAge(int a){age = a;}// public void setName(String n){// name = n;// }// public void setName(String name){ //调用此方法时,参数name与属性name混乱,name无法完成赋值操作// name = name;// }public void setName(String name){ //this.name = name;}public void info(){System.out.println("name: " + name + "age: " + age);}
}
输出结果:
- 在方法内部使用,即此方法所属对象的引用
- 在构造器内部使用,表示该构造器正在初始化的对象
- 在构造器中,可以使用"this(形参)"的方式显示调用本类其他重载的指定
- 构造器
必须声明在首行;
如一个类中有n个构造器,那么最多可以有n-1个构造器可以使用this(形参)
练习
题一
//这些类可以写在不同的文件里
public class Test3 { public static void main(String[] args) {Boy boy = new Boy();boy.setAge(22);boy.setName("钱三一");Girl girl = new Girl();girl.setName("林妙妙");boy.marry(girl);boy.shout();System.out.println(" ");girl.marry(boy);}
}class Boy{ private String name;private int age;public void setName(String name){this.name = name;}public void setAge(int age){this.age = age;}public String getName( ){return name;}public String getAame( ){return age;}public void marry(Girl girl){System.out.println("我\u60F3要娶:" + girl.getName());}public void shout(){if(age > 24){System.out.println("我们可以先结婚");}else{System.out.println("\u6211\u4EEC可以先谈谈");}}
}class Girl{private String name;public void setName(String name){this.name = name;}public String getName(){return name;}public void marry(Boy boy){System.out.println("我想要嫁给:" + boy.getName());boy.marry(this);}
}
package
- 声明源文件所在包,写在程序的第一行
- 每"."一次,代表一层文件目录
- 包名都要小写
- package语句后面的分号不要掉
例:
package com.huwei.t1;(com是一个文件夹,huwei是com下的一个文件夹,t1是huwei文件夹下的一个文件夹)
个人的项目命名
indi
个体项目(individual),指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者。
包名为“indi.发起者名.项目名.模块名……
”
onem
单人项目(one-man),推荐用indi,指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者。
包名为“onem.发起者名.项目名.模块名……
”
pers
个人项目(personal),指个人发起,独自完成,可分享的项目,copyright主要属于个人。
包名为“pers.个人名.项目名.模块名.……
”
priv
私有项目(private),指个人发起,独自完成,非公开的私人使用的项目,copyright属于个人。
包名为“priv.个人名.项目名.模块名.……”
团体的项目命名
team
团队项目,指由团队发起,并由该团队开发的项目,copyright属于该团队所有。
包名为“team.团队名.项目名.模块名.……
”
com
公司项目,copyright由项目发起的公司所有。
包名为“com.公司名.项目名.模块名.……
”
import
- 显式导入指定包下的类或接口
import java.util,Scanner;
- 写在包声明与源文件之间
- 如果引用多个类或接口,就需要并列写出
import java.util.Scanner;
import java.util.Date;
- import语句后面的分号不要掉
- 程序默认导入的是java.lang下的所有类和接口(即System,int,Math等),使用时不需要再次导入
- 导入一个包下的所有类可以使用*代替
import java.util.*;
- 同名类的导入(如util与sql下都有Date类)就需要用常规方法导入其中一个类,另一个同名的就直接用包名.类名表示
如:java.sql.Date d1 = new java.sql.Date(234435L)
import satic
表示导入指定类的static的属性或方法
如:
引用:import java.lang.System.out;
调用:out.println("hello world!")
import java.util.*
只能导入java.util下的所有类和接口,不能导入lang下的子包中的类和接口。
super
可以修饰属性,方法,构造器
- 若子类与父类中的属性有重名,可以用”super.属性“来显示调用父类声明中的属性,”this.属性“来显示调用子类声明中的属性。
- 若子类与父类中的方法有重名,可以用”super.方法()“来显示调用父类声明中的属性,”this.属性“来显示调用子类声明中的属性。
- 在子类中使用”super(形参列表)“来显式调用父类中指定的构造器。
在构造器内部,”super(形参列表)“必须声明在首行,
在构造器内部,”super(形参列表)“和”this(参数列表)“只能存在其一,
建议:设计一个类时,尽量要提供一个空参的构造器。
在构造器中,不显示的调用”super(形参列表)“或”this(参数列表)“其中一个,那默认调用的是父类空参的构造器。)
// 父类
class Person{ private int sex; int id = 111;//身份证号public Person(int sex){ this.sex = sex; }public Person(){ System.out.println("我是父类空参构造器");}public int getSex() {return sex; }public void setSex(int sex) { this.sex = sex; } public void manOrWorman(){ if(sex == 1){System.out.println("man"); }if(sex == 0){ System.out.println("woman"); }}
}
//子类class Student extends Person{ private int yearOld; int id = 222;//学号 //子类调用父类的构造器public Student(int yearOld){ super(1); this.yearOld = yearOld; }public Student(){//此时程序也会调用父类空参的构造器this.yearOld = 33; }public void yearOld(int yearOld){ this.yearOld = yearOld; }public void printAge(){ System.out.println("yearOld: " + yearOld); }public void show(){ System.out.println(id);//222(子类) System.out.println(super.id);//111(父类) }}public class Test3{public static void main(String[] args) {Student student = new Student();student.setSex(0);student.yearOld(14);student.manOrWorman();student.printAge();student.show();}
}
感谢大家的支持,关注,评论,点赞!
参考资料:
尚硅谷宋红康20天搞定Java基础上部
Java包(package)的命名规范&规则