继承
- 将多个类中共有的属性,方法剥离出来单独创建一个共有类,当需要使用共有的属性与方法时,就可以通过继承(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)的命名规范&规则