面向对象特征----继承
继承概念
package com.cloud.day4; /* 在现实生活中事物与事物之间是存在关系. 球员---->球队 整体与部分关系 has a 关系 学生----->人 继承的关系 is a 关系 */ class Player{ int num; String name; public Player(int num,String name){ this.num = num; this.name = name; } public void run(){ System.out.println(name+"running...."); } } class Team{ String name; Player p1; Player p2; Player p3; public Team(String name,Player p1,Player p2,Player p3){ this.name=name; this.p1=p1; this.p2=p2; this.p3=p3; } public void satartGame(){ System.out.println(name+"开始比赛..."); } } public class Demo5 { public static void main(String[] args) { Player p1 = new Player(12,"梅西"); Player p2 = new Player(7,"C罗"); Player p3 = new Player(11,"内马尔"); //球队 Team t = new Team("恒大",p1,p2,p3); t.satartGame();
System.out.println("名字:"+ t.p2.name); } } |
继承注意事项
package com.cloud.day4; /* 目前存在的问题: 1. 无法描述清楚这两个类之间的继承关系。 2. 存在着重复代码。 面向对象的三大特征: 1. 封装 2. 继承 3. 多态. 继承:继承是通过关键字extends体现的。 继承的格式: class 类名1 extends 类名2{ } 继承要注意的事项: 1. 千万不要为了减少重复代码而去继承,只有真正存在着继承关系的时候才去继承。 2. 父类私有的成员不能被继承。 3. 父类的构造函数不能被继承。 4. 创建子类对象时默认会先调用父类无参的构造函数。 */ class Person{ String name; private int age; public Person(String name){ this.name = name; } public Person(){ System.out.println("调用了Person的构造方法"); } public void eat(){ System.out.println(name+"吃饭..."); } } class Child extends Person{ int num; public Child(){ System.out.println("调用了Student的构造方法"); } public void study(){ System.out.println(name+"好好学习"); } } public class Demo6 { public static void main(String[] args) { Child c = new Child(); c.name="summer"; c.study(); } } |
构造方法在继承中的使用
package com.cloud.day4; /* 调用父类构造方法的意义 初始化从父类继承下的属性 */ class Fu{ int x = 10; String name; public Fu(String name){ this.name = name; System.out.println("父类带参数的构造方法..."); } public Fu(){ System.out.println("父类无参数的构造方法..."); } } class Zi extends Fu{ int x = 20; public Zi(String name){ //指定调用父类带参数的构造函数 super(name); } public void print(){ System.out.println(x); } } public class Demo7 { public static void main(String[] args) { Zi z = new Zi("we"); System.out.println(z.name); z.print(); } } |
Super关键字
package com.cloud.day4; /* super关键字: super关键字代表了父类空间的引用。 super关键字的作用: 1. 子父类存在着同名的成员时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员。 2. 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法。
super关键字调用父类构造方法要注意的事项: 1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。 2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句。 3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。 super关键字与this关键字的区别: 1. 代表的事物不一致。 1. super关键字代表的是父类空间的引用。 2. this关键字代表的是所属函数的调用者对象。 2. 使用前提不一致。 1. super关键字必须要有继承关系才能使用。 2. this关键字不需要存在继承关系也可使用。 3. 调用构造函数的区别: 1. super关键字是调用父类的构造函数。 2. this关键字是调用本类的构造函数。 */ class Fu1{ int x=10; String name ; public Fu1(){ System.out.println("父类无参构造方法..."); } public Fu1(String name){ this.name = name; } public void eat(){ System.out.println("Fu1 eat..."); } } class Zi1 extends Fu1{ int x = 20; int num; public Zi1(String name,int num){ //调用父类带参数的 super(name); //调用本类无参构造方法 //this(); System.out.println("Zi1带参数的构造方法..."); } public Zi1(){ System.out.println("Zi1无参构造方法..."); } public void print(){ System.out.println("x = " +super.x); } public void eat(){ System.out.println("大头儿子吃龙虾.."); } } public class Demo8 { public static void main(String[] args) {
} } |
方法重写
package com.cloud.day4; /* 目前的问题:父类的功能无法满足子类的需求。
方法重写的前提:必须要存在继承的关系。 方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。 什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。
方法重写要注意的事项: 1.方法重写时,方法名与形参列表必须一致。 2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。 3.方法重写时,子类的返回值类型必须要小于或者等于父类的返回值类型。 4.方法重写时,子类抛出的异常类型要小于或者等于父类抛出的异常类型。 Exception(最坏) RuntimeException(小坏)
方法的重载:在一个类中存在两个或者两个以上的同名函数,称作为方法重载。
方法重载的要求 1. 函数名要一致。 2. 形参列表不一致(形参的个数或形参的类型不一致) 3. 与返回值类型无关。 */
//大的数据类型 class Animal{} //小的数据类型 class Fish extends Animal{} class Fu2{ String name; public Fu2(String name){ this.name = name; } public Animal eat() throws RuntimeException{ System.out.println(name+"eat..."); return new Animal(); } } class Zi2 extends Fu2{ String num; public Zi2(String name){ super(name);//指定调用父类带参的构造方法 } //重写父类的eat方法 public Animal eat() throws RuntimeException{ System.out.println("吃点开胃菜.."); System.out.println("喝点汤...."); System.out.println("吃点龙虾...."); return new Animal(); } } public class Demo9 { public static void main(String[] args) { Zi2 z = new Zi2("大头儿子"); z.eat(); } } |
继承案例
package com.cloud.day4;
/* 需求:使用java描述一下普通的学生、 java基础班的学生、就业班的学生。 所有的学生都会学习。但是学习的内容不一样。 普通的学生:马克思列宁主义。 基础班的学生:学习的是 javase。 就业班学生: javaee+android. */ class Student1{ String name; public Student1(String name){ this.name = name; } public void study(){ System.out.println(name+"study..1..."); } } class BaseStudent extends Student1{ public BaseStudent(String name) { super(name); } public void study(){ System.out.println(name+"study...java..."); } } public class Demo10 { public static void main(String[] args) {
} } |
Instanceof关键字
package com.cloud.day4; /* instanceof关键字 instanceof关键字的作用:判断一个对象是否属于指定的类别。 instanceof关键字的使用前提:判断的对象与指定的类别必须要存在继承或者实现的关系。 instanceof关键字的使用格式: 对象 instanceof 类别 instanceof关键字的作用:到了多态之后就非常有用。 一般我们做强制类型转换之前都会使用该关键字先判断一把,然后在进行转换的。 */ class Animal1{ String name; String color; public Animal1(String name,String color){ this.name = name; this.color = color; } } class Dog extends Animal1{ public Dog(String name, String color) { super(name, color); } public void bite(){ System.out.println(name+"bite..."); } } class Mouse extends Animal1{ public Mouse(String name, String color) { super(name, color); } public void dig(){ System.out.println(name+"打洞..."); } } public class Demo11 { public static void main(String[] args) { Dog d = new Dog("哈士奇","白色"); System.out.println(d instanceof Dog); System.out.println(d instanceof Animal1); Animal1 a = new Animal1("小白","黑的"); System.out.println(a instanceof Dog); } } |
Final关键字
package com.cloud.day1; /* final(最终、修饰符) final关键字的用法: 1. final关键字修饰一个基本类型的变量时,该变量不能重新赋值,第一次的值为最终的。 2. fianl关键字修饰一个引用类型变量时,该变量不能重新指向新的对象。 3. final关键字修饰一个函数的时候,该函数不能被重写。 4. final关键字修饰一个类的时候,该类不能被继承。 常量的修饰符一般为: public static final */ class Circle{ double r; public static final double pi = 3.14; public Circle(double r){ this.r = r; } public final void getArea(){ System.out.println("面积:"+pi*r*r); } } public class Demo1 extends Circle{ public Demo1(double r) { super(r); } public static void main(String[] args) { Circle c = new Circle(4.0); c.getArea(); } } |
抽象类
package com.cloud.day1; /* 抽象类: 目前存在的问题: 1. 动物类的run方法描述的不正确。 2. 没有强制要子类一定要重写run方法。
抽象类的应用场景: 我们在描述一类事物的时候,发现该种事物确实存在着某种行为, 但是这种行为目前是不具体的,那么我们可以抽取这种行为的声明,但是 不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类。
抽象类的好处: 强制要求子类一定要实现指定的方法。 抽象类要注意的细节: 1. 如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象的函数。。 2. 如果一个类出现了抽象的函数,那么该类也必须使用abstract修饰。 3. 如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。 4. 抽象类可以存在非抽象方法,也可以存在抽象的方法. 5. 抽象类可以不存在抽象方法的。 5. 抽象类是不能创建对象的。 疑问:为什么抽象类不能创建对象呢? 因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象的对象.调用抽象方法是没有任何意义的。 6. 抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。 */ abstract class Animal{ String name; String color; public Animal(String name,String color){ this.name = name; this.color = color; } public void eat(){ System.out.println(name+"eat..."); } public abstract void run(); } class Dog extends Animal{ public Dog(String name, String color) { super(name, color); } public void run(){ System.out.println(name+"跑啊跑..."); } } public class Demo2 { public static void main(String[] args) { Dog d = new Dog("哈哈", "白色"); d.run(); //Animal a = new Animal("11","22"); //a.run(); } } |
继承中的值传递
package com.cloud.day1; /* java 单继承特点,但是可以间接多继承 */ class Ye{ String name; } class Fu extends Ye{} class Zi extends Fu{} public class Demo5 { public static void main(String[] args) { Zi z = new Zi(); z.name = "haha"; } } |
间接继承
package com.cloud.day1; /* java 单继承特点,但是可以间接多继承 */ class Ye{ String name; } class Fu extends Ye{} class Zi extends Fu{} public class Demo5 { public static void main(String[] args) { Zi z = new Zi(); z.name = "haha"; } } |
继承案例
package com.cloud.day1; /* 需求:描述一个图形、圆形、矩形三个类。不管哪种图形都会具备计算面积 与周长的行为,但是每种图形计算的方式不一致而已。 常量的命名规范:全部字母大写,单词与单词之间使用下划线分隔。 abstract不能与以下关键字共同修饰一个方法: 1. abstract不能与private共同修饰一个方法。 2. abstract 不能与static共同修饰一个方法。 3. abstract 不能与final共同修饰一个方法。 */ abstract class MyShap{ String name; public MyShap(String name){ this.name = name; } public abstract void getArea(); public abstract void getLength(); } class Circle1 extends MyShap{ double r; public static final double PI = 3.14; public Circle1(String name,double r) { super(name); this.r = r; } @Override public void getArea() { System.out.println(name+"的面积:"+PI*r*r); } @Override public void getLength() { System.out.println(name+"的周长:"+2*r*PI); } } class Rect extends MyShap{ int width; int height; public Rect(String name,int width,int height) { super(name); this.height = height; this.width = width; } @Override public void getArea() { System.out.println(name+"面积:"+height*width); } @Override public void getLength() { System.out.println(name+"周长:"+2*(height+width)); } } public class Demo3 { public static void main(String[] args) { Circle1 c1 = new Circle1("aa",6); c1.getArea(); c1.getLength(); Rect rt = new Rect("bb", 2, 4); rt.getArea(); rt.getLength(); } } |