【0基础学java】教学日志:javaSE-面向对象4-继承、super、方法重写、抽象类、抽象方法、final、Object类

本章概述
本章属于面向对象第三章的内容,主要讲解继承、super、方法重写、抽象类、抽象方法、final、Object类等知识点。

​一、继承
 
1、为什么要使用继承?
使用继承优化后:
 
子类和父类是is-a的关系
2、继承是什么?
  • 类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。
  • 提高代码的复用性!
  • extends的意思是“扩展”。子类是父类的扩展
  • 不同的叫法:超类、父类、基类、子类、派生类
3、如何使用继承?
使用继承
--编写父类
--编写子类,继承父类
--一个类只能继承一个父类
4、课堂Demo【重点掌握】
子类 Dog.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 15:24 * @Description: netclass03.extend * @version: 1.0 */ public class Dog extends Pet { // private String name; // private int age; // private String gender; private String sound; public Dog(){ // super(); } // public Dog(String name){ // super(name); // } // // public Dog(int age,String gender){ // super(age,gender); // } public Dog(String name, int age, String gender, String sound) { // super(); // super(name); // this(age,gender); super(name,age,gender); // this.name = name; // this.age = age; // this.gender = gender; this.sound = sound; } // public String 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 String getGender() { // return gender; // } // // public void setGender(String gender) { // this.gender = gender; // } public String getSound() { return sound; } public void setSound(String sound) { this.sound = sound; } public void show(){ // System.out.println("name:" +this.name +" age:" +this.age +" gender:" +this.gender +" sount:" +this.sound); System.out.println("name:" +this.getName() +" age:" +this.getAge() +" gender:" +this.getGender() +" sount:" +this.sound); } @Override public void print(){ System.out.println("Dog print... ..."); // super.print(); } }
​子类 Penguin.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 15:25 * @Description: netclass03.extend * @version: 1.0 */ public class Penguin extends Pet { // private String name; // private int age; // private String gender; private String color; public Penguin(){ } public Penguin(String name, int age, String gender, String color) { super(name,age,gender); // this.name = name; // this.age = age; // this.gender = gender; this.color = color; } // public String 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 String getGender() { // return gender; // } // // public void setGender(String gender) { // this.gender = gender; // } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void show(){ // System.out.println("name:" +this.name +" age:" +this.age +" gender:" +this.gender +" color:" +this.color); System.out.println("name:" +this.getName() +" age:" +this.getAge() +" gender:" +this.getGender() +" color:" +this.color); } }
父类Pet.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 15:33 * @Description: netclass03.extend * @version: 1.0 */ public class Pet { private String name; private int age; private String gender; public Pet(){ // super(); //指向顶级父类Object System.out.println("Pet 空构造器... ..."); } // public Pet(String name){ // this.name= name; // } // // public Pet(int age,String gender){ // this.age = age; // this.gender = gender; // } public Pet(String name, int age, String gender) { System.out.println("Pet(String name, int age, String gender)... ..."); this.name = name; this.age = age; this.gender = gender; } public String 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 String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public /*static*/ void print(){ System.out.println("Pet print... ..."); } private void test(){ System.out.println("Pet test... ..."); } }
测试类PetTest.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 15:25 * @Description: netclass03.extend * @version: 1.0 */ /* * 继承: * 表示父类跟子类之间的关系 * 当两个类或者多个类具备相同的属性和方法的时候,可以提取出来,变成父类,子类可以继承 * * 子类跟父类是is-a的关系 * * 使用: * 1、使用继承的时候需要使用extends关键字 * 2、使用继承关系之后,父类中的属性和方法都可以在子类中进行使用(非私有属性和非私有方法) * 3、java中是单继承关系(如果包含多个父类,同时父类中包含重名方法,无法决定该调用谁) * * * super:是 直接父类 对象的引用 * 用途: * 1、可以在子类中调用父类中被子类覆盖的方法 super.父类方法名称 * 2、当super在普通方法中使用的话,可以任意位置编写 * 3、当super在构造方法中使用的话,会调用父类的构造方法,一定要将super放在第一行 * 4、在构造方法中super关键字和this关键字(指的是不能同时使用this关键字调用重载的构造方法)不能同时出现 * 5、父类中私有的属性和方法都不能被调用,包括构造方法 * 6、子类的构造方法中都会默认使用super关键字调用父类的无参构造方法,因此在定义类的时候,无论自己是否自定义了 * 其他构造方法,最好将无参构造方法写上 * 7、如果构造方法中显式的指定了super的构造方法,那么无参的构造方法就不会被调用 * * 总结: * 1、在创建子类对象的时候一定会优先创建父类对象 * 2、所有的java类都具备同一个顶级父类(老祖宗),称之为Object,是所有类的根类 * * 重写:(覆盖)override * 必须要存在继承关系,当父类中的方法无法满足子类需求的时候可以选择使用重写的方式 * 注意: * 1、重写表示的是子类覆盖父类的方法,当覆盖之后,调用同样的方法的时候会优先调用子类 * 2、重写的方法名称,返回值类型,参数列表必须跟父类一致 * 3、子类重写的方法不允许比父类的方法具备更小的访问权限 * 父类 public 子类 public * 父类 protected 子类 public protected * 父类 default 子类 public protected default * 父类的静态方法子类可以进行调用,但是子类不可以重写 * */ public class PetTest { public static void main(String[] args) { // Dog dog = new Dog(); // dog.name = "xiaohei"; // dog.setName("小白"); // dog.setAge(10); // dog.setGender("雄性"); // dog.setSound("汪汪汪~~"); // dog.show(); // dog.print(); Dog dog = new Dog("小白",10,"雄性","汪汪汪~~"); dog.print(); // dog.name = "小黑"; // dog.test(); // Dog dog = new Dog(); // Penguin p = new Penguin("小白",11,"雌性","olive"); // p.show(); } }
2、java中只有单继承,也就是从子类出发只能有一个直接父类。课堂代码【重点掌握】
父类1--Father1.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 16:12 * @Description: netclass03.extend * @version: 1.0 */ public class Father1 { public void test(){ System.out.println("Father1 test... ..."); } }
父类2--Father2.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 16:12 * @Description: netclass03.extend * @version: 1.0 */ public class Father2 { public void test(){ System.out.println("Father2 test... ..."); } }
子类--SubClassTest.java
package netclass03.extend; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 16:13 * @Description: netclass03.extend * @version: 1.0 */ public class SubClassTest extends Father1/*,Father2*/ { public static void main(String[] args) { // Father1 father1 = new Father1(); // father1.test(); SubClassTest sct = new SubClassTest(); sct.test(); } }
3、其他代码--课堂Demo【重点掌握】
PetClassTest.java
package netclass03; import netclass03.extend.Pet; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 17:01 * @Description: netclass03 * @version: 1.0 */ public class PetClassTest extends Pet { public static void main(String[] args) { PetClassTest pct = new PetClassTest(); pct.print(); } }
Tiger.java--演示在类中创建set,get方法时,如果出现boolean类型的成员变量,get方法要以is开头。
package netclass03; /** * @Auther: Yu Panpan * @Date: 2022/1/10 - 01 - 10 - 14:54 * @Description: netclass03 * @version: 1.0 */ public class Tiger { private String name; private int age; private boolean isAnimal; public Tiger(){ } public Tiger(String name, int age, boolean isAnimal) { this.name = name; this.age = age; this.isAnimal = isAnimal; } public String 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 boolean isAnimal() { return isAnimal; } public void setAnimal(boolean animal) { isAnimal = animal; } }
二、继承的理解和super【课堂Demo同上】
1、super是直接父类对象的引用。
2、可以通过super来访问父类中被子类覆盖的方法或属性。
3、普通方法:
没有顺序限制。可以随便调用。
4、构造函数中:
任何类的构造函数中,若是构造函数的第一行代码没有显式的调用super(...);那么
Java默认都会调用super();作为父类的初始化函数。 所以你这里的super();加不加
都无所谓。
5、super实例代码
public class Test { public static void main(String[] args) { new ChildClass().f(); } } class FatherClass { public int value; public void f(){ value = 100; System.out.println ("FatherClass.value="+value); } } class ChildClass extends FatherClass { public int value; public void f() { super.f(); value = 200; System.out.println("ChildClass.value="+value); System.out.println(value); System.out.println(super.value); } }
6、理解继承:
a、子类访问父类成员
使用super关键字代表父类对象
---- 访问父类构造方法
super(); super(name);
在子类构造方法中调用且必须是第一句
---- 访问父类属性
super.name;
---- 访问父类方法
super.print();
b、子类可以继承父类的所有资源吗?
不能被继承的父类成员有哪些?
---- 不能直接访问private成员
---- 子类与父类不在同包,使用默认访问权限的成员
---- 构造方法不能被继承
c、访问修饰符protected
---- 可以修饰属性和方法
---- 本类、同包、子类可以访问
d、访问修饰符总结
 
e、多重继承关系的初始化顺序是怎样的?
1、父类属性---->2、父类构造方法---->3、子类属性---->4、子类构造方法
f、理解继承示例代码
public class TestExtends { public static void main(String[] args) { Mammal m1 = new Mammal(); m1.puru(); m1.eat(); } } class Animal { String eyes="眼睛"; String name="无名"; public void eat(){ System.out.println("动物吃东西!"); } } class Mammal extends Animal { //哺乳 public void puru(){ eyes=“嘴巴”; System.out.println("小动物吃奶!"); } }
g、在何处使用继承?
何时使用继承?
---- 继承和真实世界类似
---- 只要说“猫是哺乳动物”,猫的很多属性、行为就不言自明了
---- 藏獒是一种狗
符合is-a关系的设计使用继承
---- 继承是代码重用的一种方式
将子类共有的属性和行为放到父类中
h、代码分析
class Car { private int site = 4; //座位数 Car(){ System.out.println ("载客量是"+site+"人); } public void setSite(int site){ this.site = site; } void print(){ System.out.println ("载客量是"+site+"人); } } class Bus extends Car { Bus(int site){ setSite(site); } } public class BusTest{ public static void main(String[] args) { Bus bus = new Bus(20); bus.print(); } }
i、小结
---- 通过继承可以简化类的定义,实现代码的重用
---- 子类继承父类的成员变量和成员方法,但不继承父类的构造方法
---- java中只有单继承 ,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复
杂,系统难于维护。就像我们现实中,如果你有多个父母亲,那是一个多么混乱的世界啊。多继
承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。
---- java中的多继承,可以通过接口来实现
---- 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
三、方法重写【课堂Demo同上】
1、在子类中可以根据需要对从基类中继承来的方法进行重写。
2、重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
3、重写方法不能使用比被重写方法更严格的访问权限。(由于多态)
4、重写示例代码
public class TestOverride { public static void main(String[] args) { Animal animal = new Animal(); animal.shout(); Dog dog = new Dog(); dog.shout(); } } class Animal{ void shout(){ System.out.println("发出声音!"); } } class Dog extends Animal { void shout(){ System.out.println("旺旺旺!"); } }
5、小结:
---- 构造方法也会被重写吗?
不能被继承,因此不能重写
---- 方法重写的规则
方法名相同
参数列表相同
返回值类型相同或者是其子类;
访问权限不能严于父类
---- 方法重载与方法重写的区别
 
---- super关键字来访问父类的成员
---- super只能出现在子类的方法和构造方法中
---- super调用构造方法时,只能是第一句
---- super和this不能同时出现在构造方法中
---- super不能访问父类的private成员
---- super和this都不能再static方法中
 
四、抽象类、抽象方法
1、课堂Demo【重点掌握】
父类 Pet.java
package netclass04.abstracts; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 14:36 * @Description: netclass04.abstracts * @version: 1.0 */ public abstract class Pet { private String name; private int age; public Pet(){ } public Pet(String name,int age){ this.name = name; this.age = age; } //抽象方法 public abstract void print(); public void show(){ System.out.println("Pet show... ..."); } }
子类 Dog.java
package netclass04.abstracts; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 14:39 * @Description: netclass04.abstracts * @version: 1.0 */ public class Dog extends Pet{ private String gender; @Override public void print() { System.out.println("dog print... ..."); } }
测试类 PetTest.java
package netclass04.abstracts; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 14:41 * @Description: netclass04.abstracts * @version: 1.0 */ /* * java中的对象是对现实世界的具象化,但是在现实世界中,某些类并不具备实例化的意义,因此可以定义为抽象类 * * 抽象类: * 1、创建抽象类的时候需要添加 abstract 的关键字 * 2、不能进行实例化,也就是不能new对象 * 3、抽象类中的某些方法需要子类进行更丰富的实现,父类实现没有意义,此时可以将抽象类 * 中的方法定义为抽象方法,没有具体的实现,只包含方法名称,返回值,参数列表,访问修饰符 * 4、使用abstract关键字修饰的方法叫做抽象方法,可以不写方法的实现 * 5、子类在继承抽象父类的时候,必须要将父类中的抽象方法进行实现或者将子类也定义为抽象类 * 6、有抽象方法的一定是抽象类,但是抽象类中不一定包含抽象方法 * */ public class PetTest { public static void main(String[] args) { Dog dog = new Dog(); dog.print(); // Pet pet = new Pet(); } }
五、final
1、课堂Demo【重点掌握】
FinalDemo.java
package netclass04.abstracts; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 14:54 * @Description: netclass04.abstracts * @version: 1.0 */ /* * final的使用: * final可以修饰变量: * 表示变量的值不可变 * final可以修饰方法: * 表示方法不可以被重写 * final可以修饰类: * 表示类不可以被继承 * * */ public /*final*/ class FinalDemo { private String name; // public FinalDemo(){ // super(); // } public String getName() { return name; } public void setName(String name) { this.name = name; } public static final int num = 10; public final void show(){ System.out.println("FinalDemo... ..."); } public static void main(String[] args) { // FinalDemo fd = new FinalDemo(); // fd.num = 20; // FinalDemo.num = 20; // num = 20; // System.out.println(num); final FinalDemo fd = new FinalDemo(); fd.show(); // fd = new FinalDemo(); fd.setName("jason"); System.out.println(fd.getName()); } }
FinlaSubClass.java
package netclass04.abstracts; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 14:59 * @Description: netclass04.abstracts * @version: 1.0 */ public class FinalSubClass extends FinalDemo{ // @Override // public void show(){ // // } }
六、Object类
1、Object类是所有类的父类
一个类如果没有使用extends显性的继承另外一个类,那么这个类就继承自Object类。
2、源码解析(涉及到Object中常用的10个方法)
getClass()、hashCode()、equals(Object)、clone()、toString()、notify()、notifyAll()、wait()、wait(long)、wait(long,int)
 
finalize()方法为过时的方法或者说是不推荐的方法,主要作用是标识在堆中的对象哪些是没有被引用的,方便JVM中的GC进行垃圾回收。
3、对象的比较—==和equals()
a、==:
---- 比较两基本类型变量的值是否相等
---- 比较两个引用类型的值即内存地址是否相等,即是否指向同一对象。
b、equals() :
两对象的内容是否一致
c、自定义类须重写equals(),否则其对象比较结果总是false。
通过阅读Object源码可知,equals()方法的实现是用==完成的
Object源码摘抄 public boolean equals(Object obj) { return (this == obj); }
4、Object课堂Demo【重点掌握】
package netclass04.abstracts; import java.util.Objects; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 15:14 * @Description: netclass04.abstracts * @version: 1.0 */ public class Teacher{ private String name; private int age; private double salary; public Teacher() { } public Teacher(String name, int age, double salary) { this.name = name; this.age = age; this.salary = salary; } public String 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 double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } // @Override // public boolean equals(Object o){ // Teacher t =(Teacher) o; // return (this.name == t.name && this.age == t.age && this.salary == t.salary); // } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Teacher teacher = (Teacher) o; return age == teacher.age && Double.compare(teacher.salary, salary) == 0 && Objects.equals(name, teacher.name); } @Override public int hashCode() { return Objects.hash(name, age, salary); } @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}'; } // @Override // public String toString(){ // return "name:" +this.name +" age:" +this.age +" salary:" + this.salary; // } public static void main(String[] args) { Teacher t1 = new Teacher("张飞",28,9000); // Teacher t2 = t1; Teacher t2 = new Teacher("张飞",28,9000); // System.out.println(t1 == t2);//true false // t2.setName("赵云"); System.out.println(t1.equals(t2));//true false System.out.println(t1);}}
七、总结
1、继承深化
a、父类方法的重写:
---- 方法名、形参列表相同。
---- 返回值类型和异常类型,子类小于等于父类。
---- 访问权限,子类大于等于父类
b、构造方法调用顺序:
---- 根据super的说明,构造方法第一句 总是:super(…)来调用父类对应的构造方法。
---- 先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。
八、作业
1、上机练习--课堂Demo【重点掌握】
某汽车租赁公司出租多种车辆,车型及租金情况如下:
 
编写程序实现计算租赁价
案例分析:
a、发现类
MotoVehical(机动车,抽象类)、Car、Bus
b、发现类的属性
---- MotoVehical:no(车牌号),brand(品牌)
---- Car:type(型号)
---- Bus:seatCount(座位数)
c、发现类的方法
---- MotoVehical:calcRent(int days) 抽象方法
---- Car:Car(no,brand,type) 构造方法
---- Bus:Car(no,brand,seatCount) 构造方法
d、优化设计,编写程序
机动车类:MotoVehical.java
package netclass04.abstracts.homework; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 16:23 * @Description: netclass04.abstracts.homework * @version: 1.0 */ public abstract class MotoVehical { private String no; private String brand; public MotoVehical(){ } public MotoVehical(String no, String brand) { this.no = no; this.brand = brand; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } //抽象方法(根据天数计算租金) public abstract int calcRent(int days); }
轿车类:Car.java
package netclass04.abstracts.homework; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 16:25 * @Description: netclass04.abstracts.homework * @version: 1.0 */ public class Car extends MotoVehical { private String type; public Car(){ } public Car(String no,String brand,String type){ super(no,brand); this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public int calcRent(int days) { if(this.type.equals("0")){ return 600 * days; }else if(this.type.equals("1")){ return 500 * days; }else if(this.type.equals("2")){ return 300 * days; }else{ System.out.println("您输入的车型不存在!"); return 0; } } }
客车类:Bus.java
package netclass04.abstracts.homework; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 16:28 * @Description: netclass04.abstracts.homework * @version: 1.0 */ public class Bus extends MotoVehical { private int seatCount; public Bus(){ } public Bus(String no,String brand,int seatCount){ super(no,brand); this.seatCount = seatCount; } public int getSeatCount() { return seatCount; } public void setSeatCount(int seatCount) { this.seatCount = seatCount; } @Override public int calcRent(int days) { if(this.seatCount > 16){ return 1500 * days; }else{ return 800 * days; } } }
测试类:MotoVehicalTest.java
package netclass04.abstracts.homework; /** * @Auther: Yu Panpan * @Date: 2022/1/12 - 01 - 12 - 16:30 * @Description: netclass04.abstracts.homework * @version: 1.0 */ public class MotoVehicalTest { public static void main(String[] args) { // MotoVehical moto = new MotoVehical(); Car car = new Car("豫A 8888888","别克","0"); int total1 = car.calcRent(5); System.out.println("租金为:" +total1); Bus bus = new Bus("豫A 6666666","金杯",16); int total2 = bus.calcRent(5); System.out.println("租金为:" +total2); } }
2、上机练习
 
posted @ 2022-01-13 11:45  jason的java世界  阅读(200)  评论(0编辑  收藏  举报