java父子类重载和重写

java父子类重载和重写 1.面向对象思想概述以前的代码每一个具体的步骤我们都是参与者并且需要面对具体的每一个步骤和过程这就是面向过程最直接的体现。面向过程的代表语言是C语言。把上面的步骤和功能进行封装功能类似的封装在一起这样代码的结构就清晰很多找到对应的类就可以使用这就是面向对象思想。面向对象思想:面向对象思想是基于面向过程的编程思想。面向过程:强调的是每一个功能的步骤面向对象:强调的是对象由对象去调用功能特点是一种更符合我们思考习惯的思想可以将复杂的事情简单化程序员从执行者变成了指挥者2.类与对象及其使用类与对象的关系学习编程语言是为了模拟现实世界的事物提高生产效率实现信息化。我们如何表示一个现实世界事物呢属性: 该事物的描述信息行为: 该事物能够做什么Java语言的最基本单位是类所有我们就把事物用类来体现。类:是一组相关的属性和行为的集合。对象:是该类事物的具体体现。java中用class描述事物:属性(成员变量):和以前定义变量一样只是在类中方法外。行为(成员方法):和以前定义方法一样只不过把static去掉。public class Student { // 属性 /** * 姓名 */ String name; /** * 年龄 */ int age; /** * 性别 */ String gender; /** * 邮箱 */ String email; // 行为 /** * 学生要吃饭 */ public void eat(){ System.out.println(学生吃火锅); } public void study(){ System.out.println(好好学习,天天向上); } }对象的创建及其使用每一个类都是一个引用数据类型创建对象:类名 对象名 new 类名(参数);使用对象访问类中的成员对象名.成员变量对象名.成员方法public static void main(String[] args) { // 类名 对象名 new 类名(参数); Student student new Student(); // cn.javasm.demo.Student3b07d329 System.out.println(student); System.out.println(student.name);// null System.out.println(student.age);// 0 System.out.println(student.email);// null System.out.println(student.gender);// null student.name 张无忌; student.age 20; student.email zhangwujiqq.com; student.gender 婉约型; System.out.println(student.name); System.out.println(student.email); student.eat(汉堡); int study student.study(); System.out.println(study); }3.对象的内存图4.成员变量和局部变量面试在类中的位置不同成员变量:类中方法外局部变量:方法中或者方法的声明上(形式参数)在内存中的位置不同成员变量:堆内存局部变量:栈内存生命周期不同成员变量:随着对象的创建而存在随着对象的消失而消失局部变量:随着方法的调用而存在随着方法的调用完毕而消失初始化值不同成员变量有默认值局部变量没有默认值必须先赋值后才可以使用5.构造方法作用:给对象的数据进行初始化格式:修饰符 构造方法名(参数列表){ }构造方法名要和类名相同没有返回值类型连void都没有没有具体的返回值构造方法是可以重载的如果没有提供任何的构造方法系统会默认提供一个无参构造如果提供了构造方法默认的无参构造就不会提供了/** * 构造方法 */ public Student(){ System.out.println(构造方法执行了); } // // public Student(String n){ // System.out.println(n); // name n; // } // // public Student(int a){ // age a; // } public Student(String n,String e,int a,String g){ name n; email e; age a; gender g; }6.privateprivate是java中的关键字是一个权限修饰符可以修饰成员变量方法构造方法。被private修饰的内容只能在本类中访问。class Student{ // private可以修饰属性 方法 构造方法 被private修饰的内容只能在本类中访问 /** * 姓名 */ private String name; /** * 年龄 */ private int age; // 提供公共的set和get方法 // set方法就是修改(设置)值 // get方法就是获取值 public void setName(String n){ name n; } public String getName(){ return name; } public void setAge(int a){ if (a 0 || a 150){ age 18; return; } age a; } public int getAge(){ return age; } public void study(){ System.out.println(name 一起学习); } public Student(String n,int a){ name n; age a; } }private最常见的应用:把成员变量用private修饰提供对应的公共的setXxx/getXxx方法封装的概述和好处封装是面向对象的三大特征之一把代码用方法进行封装提高了代码的复用性通过方法来控制成员变量的赋值提高了代码的安全性7.thisthis代表本类的对象谁调用方法就代表谁this的用法:this.成员变量访问对象的成员变量this.成员方法调用对象的成员方法this(参数)调用本类对应的构造方法package cn.javasm.demo; import java.util.Arrays; /** * author :gfs * version :1.0 * className: TestDemo * date: 2026/3/24 9:43 * description: * since :jdk17 */ public class TestDemo { public static void main(String[] args) { // 创建对象 Student student new Student(郭靖,30); // System.out.println(student.getName()); // System.out.println(student.getAge()); // student.study(); //// // Student student1 new Student(张三丰,100); // System.out.println(student1.getName()); // System.out.println(student1.getAge()); } } class Student{ // private可以修饰属性 方法 构造方法 被private修饰的内容只能在本类中访问 /** * 姓名 */ private String name; /** * 年龄 */ private int age; // 提供公共的set和get方法 // set方法就是修改(设置)值 // get方法就是获取值 public void setName(String name){ this.name name; } public String getName(){ return name; } public void setAge(int age){ if (age 0 || age 150){ this.age 18; return; } this.age age; } public int getAge(){ return age; } // 成员方法/对象方法/普通方法 public void study(){ System.out.println(name 一起学习); // 调用本类对应的对象方法 this.sleep(); } public void sleep(){ System.out.println(好好睡觉); } public Student(){ System.out.println(无参构造执行了); } public Student(String name,int age){ // 就近原则 // this()必须在构造方法有效代码的第一行 this(name); this.age age; } public Student(String name){ this.name name; } public Student(int age){ this.age age; } }8.构造代码块/** * 婴儿 */ class Baby{ /** * 姓名 */ String name; /** * 体重 */ double weight; { // 构造代码块 会在每一个构造方法执行之前执行 System.out.println(构造代码块执行了); this.eat(); this.cry(); } public Baby(){ } public Baby(String name){ this.name name; } public Baby(double weight){ this.weight weight; } /** * 吃 */ public void eat(){ System.out.println(生下来要吃奶); } public void cry(){ System.out.println(哇哇哇哭~); } }了解:局部代码块public static void main(String[] args) { // 匿名对象 // new Baby(6.9); // new Baby(美女); // new Baby(); { // 局部代码块 提高栈内存的利用率 int a 10; System.out.println(a); } }9.继承如果一些类中的属性和方法是重复的可以将这些重复的属性和方法提取到一个新的类中利用extends关键字让原来的类和新的类产生联系这种联系就称之为继承。提取出来的类称之为父类(超类、基类),原来的类称之为子类(派生类).子类通过继承父类可以使用父类一部分的方法和属性。注意:子类通过继承可以继承父类全部的属性和方法但是只有一部分属性和方法对子类可见。继承的优点:提高了代码的复用性注意:java中类的继承是单继承有多层继承但是没有多继承所有的类都有一个共同的父类:Objectpackage cn.javasm.demo; /** * author :gfs * version :1.0 * className: TestDemo3 * date: 2026/3/24 11:02 * description: * since :jdk17 */ public class TestDemo3 { public static void main(String[] args) { Dog dog new Dog(); dog.name 旺财; dog.kind 中华田园犬; dog.color 大黄; Cat cat new Cat(); cat.name 咪咪; cat.color 白色; cat.kind 狸花猫; dog.eat(); cat.sleep(); dog.age 10; } } // 宠物 class Pet extends Animal{ /** * 名字 */ String name; /** * 品种 */ String kind; /** * 毛色 */ String color; public void eat(){ System.out.println(吃~); } public void sleep(){ System.out.println(睡~); } } class Animal{ int age; } class Dog extends Pet{ public void look(){ System.out.println(看门护院); } } class Cat extends Pet{ }10.权限修饰符权限修饰符修饰的内容是确定可以访问的位置。本类中子类中同包类中其他类中public可以可以可以可以protected可以可以可以不可以默认可以同包子类可以可以不可以private可以不可以不可以不可以课堂练习定义一个类表示矩形(Rectangle)提供求周长和面积的方法// 定义一个类表示矩形(Rectangle)提供求周长和面积的方法 class Rectangle{ // 属性 // 长 private double length; // 宽 private double width; public Rectangle(double length,double width){ if (length 0 width 0){ this.length length; this.width width; } } public double getLength(){ return length; } public double getWidth(){ return width; } /** * 周长 * return */ public double getGirth(){ return 2 * (width length); } /** * 面积 */ public double getArea(){ return length * width; } }11.super在子类中调用父类的方法和属性用法:super.成员变量调用父类的成员变量super.成员方法调用父类的成员方法super()调用父类的构造方法/** * 宠物 */ class Pet{ private String name; String kind; public String getName() { return name; } public void setName(String name) { this.name name; } // alt insert public void eat(){ System.out.println(宠物要吃好吃的); } public Pet(String name){ this.name name; } public Pet(){ System.out.println(宠物父类无参构造); } } class Cat extends Pet{ public Cat(){ // 如果提供了super(),默认系统就不提供了 super(丁丁);// 每个构造方法都隐藏了一个super() super()是调用父类的无参构造 } public void shout(){ super.eat(); System.out.println(喵喵喵~); } } class Dog extends Pet{ public Dog(String name){ super(name); } public Dog(){ System.out.println(哈哈哈哈); } } class SubDog extends Dog{ public SubDog(String name){ super(name); } }12.重写Override在父子类中存在方法签名相同的非静态方法也称之为方法的覆盖。方法的重写要遵循两等两小一大五个原则:方法签名一致(方法名和参数类型)如果父类中的方法的返回值类型是基本数据类型和void,那么子类方法的返回值类型要和父类保持一致子类重写的方法的权限修饰符的范围要大于等于父类对应方法的权限修饰符的范围class A{ protected void m(){} } class B extends A{ public/protected void m(){} }如果父类方法的返回值类型是引用数据类型那么子类重写的方法的返回值类型要么和父类一致要么子类方法的返回值类型是父类方法返回值类型的子类class A{} class B extends A{} class C{ public A m(){ return null; } } class D extends C{ public B m(){ return null; } }异常那天再讲13.多态多态是继封装、继承之后面向对象的第三大特征。编译时多态: 方法的重载运行时多态向上转型方法的重写public class TestDemo3 { public static void main(String[] args) { // 向上转型 // 格式: 父类 对象名 new 子类(); // 用父类来声明对象用子类来创建对象 // 在使用向上转型创建对象的时候编译期间只会检查声明类型和创建的实际类型之间是否有继承关系 // 有继承关系就编译通过,但是并不知道具体是哪一个子类类型 // 到了运行阶段才会确定具体的子类类型 // 在向上转型中编译看左边运行看右边 // 向上转型能够解耦(降低耦合) Animal animal new Pig(); // animal.eat(); // Pig pig new Pig(); animalTest(animal); // Bird bird new Bird(); // animalTest(bird); } public static void animalTest(Animal animal){ // 向下转型(强转) Pig pig (Pig)animal; pig.sleep(); } // 编译时多态 重载 public void test(int a){ } public void test(){} } class Animal{ public void eat(){ System.out.println(动物要吃肉); } } class Pig extends Animal{ Override public void eat() { System.out.println(猪吃杂食); } public void sleep(){ System.out.println(猪呼呼大睡); } } class Bird extends Animal{ }思考题:为什么子类重写的方法的权限修饰符的范围要大于等于父类对应方法的权限修饰符的范围?class A{ public void m(){} } class B extends A{ private void m(){} } A a new B();// a对象的声明类型是A类所以a对象能干什么看的是A类A类告诉a对象有一个m方法可以在任何地方使用。 a.m();// a对象本质上是B类创建的所以m方法执行要看B类的内容发现B类中的m方法不能在其他类中使用为什么如果父类方法的返回值类型是引用数据类型那么子类重写的方法的返回值类型要么和父类一致要么子类方法的返回值类型是父类方法返回值类型的子类class A{} class B extends A{ public void mb(){} } class C{ public B m(){ return null; } } class D extends C{ public A m() { return null; } } C c new D();// c对象的声明类型是C类型所以C类型告诉c对象有一个m方法可以使用并且m方法的返回值类型是B B b c.m();// b对象的声明类型是B类型B类型中有个mb方法可以用 b.mb();// c对象的真正类型是D类型D类型的m方法返回的是A类型。A类型中根本就没有mb方法。