声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)
往期回顾
Java学习day07:面向对象三大特性之一:封装_凌~风的博客-优快云博客
Java学习day06:面向对象基础,构造方法,成员/局部变量_凌~风的博客-优快云博客
Java学习day05:排序,选择、冒泡、快速、二分、杨辉三角-优快云博客
......
Java学习day08:面向对象三大特性之一:继承
一、生活中的继承
这类例子其实是非常多的,最经典的:子承父业
儿子继承了某些本来属于父亲的东西。在Java中来说,就是子类继承了父类的某些属性和方法。
二、Java中的继承
2.1什么是继承?
继承的意思,就是将父类的属性和方法拿到子类中去使用
同时注意,继承是类和类之间的关系,所以继承至少得两个类
2.1.1语法格式:
class B extends A {
}
其中 B是一个类,A是一个类
B类继承了A类。 B叫A的子类。A是B的父类(超类,基类)
A类的称呼不少,但是Java里大部分还是说父类,只是说当提到超类和基类的时候,需要知道说的是啥
2.1.2示例:
class Father {
String name;
int age;
//行为
public void eat () {
System.out.println("吃大盘鸡拌面");
}
}
//使用了extends以后 Son 类就继承了Father这个类
//就意味着我Son类可以使用Father类下面某些属性和某些方法
class Son extends Father{
}
public class Demo1 {
public static void main(String[] args) {
Son son = new Son();
//发现继承以后,可以使用父类一些属性
son.name = "小骚磊";
son.age = 1;
System.out.println(son.name);
System.out.println(son.age);
son.eat();
}
}
2.2继承方法使用
由于继承是将父类的属性和方法拿到子类中去使用,这里就涉及到一个问题,哪些方法可以用,哪些方法不可以用
2.2.1.成员变量(属性):
私有的成员变量,子类无法使用的
公开的和默认的属性,子类可以继承使用的
2.2.2成员方法:
私有的成员方法,子类无法使用的
公开的和默认的成员方法,子类可以继承使用
2.2.2.1子类如何调用私有化的方法:
虽然私有化的方法无法直接调用,但是可以用公有化的setter和getter方法去调用
class Father1 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private void smoking () {
System.out.println("抽旱烟");
}
public void test () {
smoking();
}
}
class Son1 extends Father1 {
}
public class Demo2 {
public static void main(String[] args) {
Son1 son1 = new Son1();
//咋办? 可以使用setter和getter方法
//son1.name = "";
son1.setName("狗蛋");
System.out.println(son1.getName());
son1.test();
}
}
2.2.3总结:
凡是私有的 无法继承。
这里又要复习一下,Java中的三个关键字
public、protected和private 用于控制子类对父类成员的访问权限
private | 使用private修饰的成员只能在声明它的类内部访问,其他类无法访问。它提供了最低级别的访问权限,用于隐藏实现细节。 |
public | 使用public修饰的成员在任何地方都可以被访问,包括其他类、不同包中的类以及子类。它提供了最高级别的访问权限。 |
protected | 使用protected修饰的成员可以被同一包中的其他类访问,也可以被不同包中的子类访问。它提供了限制访问的权限,只有继承关系中的子类可以访问。 |
示例:
public class Parent {
public String publicField;
protected String protectedField;
private String privateField;
public void publicMethod() {
// 可以在任何地方访问
}
protected void protectedMethod() {
// 可以在同一包中的其他类和子类访问
}
private void privateMethod() {
// 只能在当前类内部访问
}
}
public class Child extends Parent {
public void accessParentFieldsAndMethods() {
publicField = "public field"; // 可以访问父类的public字段
protectedField = "protected field"; // 可以访问父类的protected字段
// privateField = "private field"; // 无法访问父类的private字段
publicMethod(); // 可以访问父类的public方法
protectedMethod(); // 可以访问父类的protected方法
// privateMethod(); // 无法访问父类的private方法
}
}
2.3构造方法
2.3.1先执行父类的构造,再执行子类的构造方法
也就意味着,即使你在main函数里只创建了子类对象,父类的构造方法也会被执行
2.3.2如果父类中有有参构造,但是没有无参构造。子类会报错
这是因为在子类的构造方法中,会默认调用父类的无参构造方法来完成父类的初始化工作。
回想之前讲过的一个知识点,一个类里默认会有无参构造,但是如果写了有参构造,就会覆盖掉无参构造,所以如果父类写了有参构造,又没有无参构造,子类就无法调用父类的无参构造方法来完成父类的初始化,就会报错。
所以大家初学的时候就记住一句话
关于构造方法:父类与子类的构造方法的形式保持一致。父类中有无参构造。子类也有无参构造。父类中没有无参构造,子类也没有无参构造方法
(实际上不是全一致,比如父类有有参和无参构造,而子类只需要有无参,也可以运行)
2.3.3示例:
class Father {
//只要是公开的或者默认的属性,子类可以使用的
public String name;//公开的一个属性
int age;//就是默认的属性
private int id;//private修饰的 子类不能使用
public Father () {
System.out.println("父类的构造方法");
}
public Father (String name) {
this.name = name;
}
//eat方法 使用public修饰的 子类可以使用
public void eat () {
System.out.println("吃窝窝头");
}
//默认的方法 子类是可以使用的
void work () {
System.out.println("开拖拉机耕地");
}
// 使用private修饰的方法就是私有化的方法,子类能调用吗?不能
private void smoking () {
System.out.println("抽旱烟");
}
}
class Son extends Father {
//在子类写有参构造即可
}
public class Demo1 {
public static void main(String[] args) {
Son son = new Son();
//验证name age在子类中可以使用的
son.name = "狗蛋";
son.age = 12;
//son.id = 12;
son.eat();//可以使用父类的公开的方法
son.work();
//不可以使用父类私有化的方法
//.son.smoking();
}
}
2.3.4继承的好处:
多个子类继承同一个父类时,就可以实现对父类代码的复用
这里又涉及到一个知识点:
Java中的继承都是单继承,也就是说只能有一个父类,但是可以多重继承,也就是说,可以B继承A,C继承B,这样C类也可以使用A类里公开的属性和方法
2.4关于父类子类的内存分析
2.5重写Override
2.5.1重写目的:
子类可以继承父类的非私有化的方法,但是有的 时候父类的需求满足不了子类的需求了,这个时候需要重写父类非私有的方法
我不知道大家有没有想过这样一个问题,为什么会有重写的出现?还是说大家只是单纯当成一个知识点记住
我看这个知识点的时候就有一个问题,既然父类里的方法不满足子类的需求,干嘛不直接在子类里重新写一个新方法呢?而是非要重写父类的?
其实很简单,因为学到后面我们会调用java封装的很多方法,继承很多父类,这些父类是Java封装好了的,我们没法改动,而这个类我们又得继承,所以我们就选择了重写
2.5.2重写要求:
1.必须有继承关系 |
2.父类的方法必须是非私有化的 |
3.必须在子类中去重写 |
4.在子类中重写父类的方法,这个方法除了方法体不一样其他都一样的。(返回值、方法名、参数类型参数名都一样的) |
2.5.3示例:
class Father {
public void eat () {
System.out.println("吃粗粮。。。。。。");
}
public void driver () {
System.out.println("开拖拉机。。。。。");
}
}
//当父类不能满足子类的需求的话可以在子类中重写父类的方法
class Son extends Father {
//重写的时候在子类中 只需要打上方法的名字一敲回车即可
//重写的方法 和父类 的 返回值 参数 方法名字 一模一样,但是方法体不一样的
@Override//是重写的严格限定,只要有这个,就证明咱们下面的这个方法
//就是重写的方法,告知程序员 此时eat方法是重写的不是自己独有的
public void eat() {
System.out.println("吃白面馒头......");
}
@Override
public void driver() {
System.out.println("开小汽车");
}
}
public class Demo1 {
public static void main(String[] args) {
Son son = new Son();
son.eat();
son.driver();
//重写的话,是不影响父类的方法的
Father father = new Father();
father.eat();
father.driver();
}
}
代码注释非常详细,大家多看代码,另外多敲代码
2.6重载Overload
2.6.1什么是重载:
在Java中同一个类中可以有很多个方法。方法名字一样。但是参数类型不一样。这种叫重载
2.6.2重载要求:
1.方法的重载必须在同一个类中 |
2.方法名字必须一致 |
3.方法的参数类型必须不一样 |
4.方法的返回值可以不一样 |
5.无参构造和有参构造 也是一种重载 |
只需要抓住,方法名一样,参数类型不一样。
2.6.3示例 :
class Person {
//在一个类中,方法法名字一样,但是参数一定不一样。这叫方法的重载
//返回值可以不一样
public void test () {
System.out.println("test");
}
public void test (String name) {
System.out.println(name);
}
public void test (int i) {
System.out.println(i);
}
void test (double d1) {
}
public String test(String str1, String str2) {
return str1 + str2;
}
}
public class Demo3 {
public static void main(String[] args) {
}
}
以上就是今天所有的知识点,下面做题:
三、习题
3.1题目
1.
Animal 类:
属性 : name, age ,sex 私有化的
方法: 吃 运动
子类:Panda
使用Panda继承Animal 并可以使用Animal下面的所有属性和方法,对属性进行赋值
方法调用2.
父类:交通工具:方法 run();
两个子类:飞机:方法 run() 高铁:方法 run() 公交车: 方法 run()
3.重写和重载的区别
建议初学者都敲一敲,而且是不看我的答案,先自己敲,很多东西看着会,实际自己上手敲的时候往往会出错。另外题解肯定不止一个,我也只是记录其中一种,大家大可寻找更优解,同时我基本没写注释,希望大家还是多自己思考原因。
3.2部分习题参考答案
2.
class Transportation {
public void run () {
System.out.println("可以跑......");
}
}
class Fly extends Transportation {
//是继承 我就u可以重写父类下面的方法了
@Override//开启重写的严格的限制,告知编译器,下面的方法必须是重写的
public void run () {
System.out.println("飞机跑的很快大概500km/h");
}
}
class Train extends Transportation {
@Override
public void run() {
System.out.println("在铁轨上跑的300km/h");
}
}
class Bus extends Transportation {
@Override
public void run() {
System.out.println("在公路上跑的60km/h");
}
}
public class Demo2 {
public static void main(String[] args) {
Train train = new Train();
train.run();
}
}
以上,就是今天的全部知识点了。可以说今天的知识点都是继承里非常重要的,希望大家都要理解清楚,敲出代码,先把继承搞清楚了,后面多态才能得心应手。
习题部分,我并没有多给,一个是很多知识点里都给了示例,另一个就是希望大家私下自己多看多练。
加油吧,预祝大家变得更强!