Java面向对象(进阶)-- super关键字的使用与子类对象实例化全过程

文章目录

  • 一、super关键字的使用
    • (1)为什么需要super?
    • (2)super的理解
    • (3)super可以调用的结构
      • 1、super调用方法
        • 举例1
        • 举例2
        • 举例3
        • 小结
      • 2、super调用属性
        • 举例1
        • 举例2
        • 举例3
        • 小结
      • 3、super调用构造器
        • 引入
        • 举例1
        • 举例2
        • 举例3
        • 举例4
      • 4、总结
        • super调用方法、属性
        • super调用构造器
    • (4)小结:this与super
      • 1、this和super的意义
      • 2、this和super的使用格式
    • (5)练习
      • 1、练习1
      • 2、练习2
      • 3、练习3
    • (6)面试题
      • 1、第一题
      • 2、第二题
      • 3、第三题
      • 4、第四题
  • 二、子类对象实例化全过程
    • (1)介绍
    • (2)举例

一、super关键字的使用

(1)为什么需要super?

举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?

可以!

举例2:子类继承父类以后,发现子类和父类中定义了同名的属性(若子类造对象,就会有两个同名属性),是否可以在子类中区分两个同名的属性?(方法可以覆盖,属性不能覆盖

可以!

如何调用? 使用super关键字即可。

(2)super的理解

super的理解:父类的

在子类中,若想调用父类中被重写的方法,就用super.方法即可;若想调用父类中的属性,就用super.属性即可。

若没有写super,调用的就是子类中重写的方法和子类里面声明的属性。

在Java类中使用super来调用父类中的指定操作:

  • super可用于访问父类中定义的属性
  • super可用于调用父类中定义的成员方法
  • super可用于在子类构造器中调用父类的构造器

注意:

  • 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
  • super的追溯不仅限于直接父类
  • super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

(3)super可以调用的结构

super可以调用的结构:属性、方法、构造器

具体的:

1、super调用方法

  • 如果子类没有重写父类的方法,只要权限修饰符允许,在子类中完全可以直接调用父类的方法;
  • 如果子类重写了父类的方法,在子类中需要通过super.才能调用父类被重写的方法,否则默认调用的子类重写的方法
举例1

观察下面代码的输出结果。

【Person.java】

package yuyi01;public class Person {//属性String name;private int age;//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}
}

【Student.java】

package yuyi01;public class Student extends Person {//属性String school;//方法public void study(){System.out.println("学生学习");}//重写public void eat(){System.out.println("学生多吃有营养的食物");}public void sleep(){System.out.println("学生保证每天不低于七小时睡眠");}
}

【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s1=new Student();s1.eat();s1.sleep();}
}

输出结果:
image.png


举例2

如何在子类方法(Student.java里面,还能够调用父类中被重写的方法呢?

如果此时在子类方法里面调用eat()方法,毫无疑问,这个eat()方法指的是自己类里面重写的方法。如下:

image.png

当然,使用eat()调用和this.eat()调用效果一样,前者只是省略了this.而已。

若现在想调用父类中的eat()方法,很简单,只需要在前面写super.即可。(以不影响封装性为前提)

【Student.java】

package yuyi01;public class Student extends Person {//属性String school;//重写public void eat(){System.out.println("学生多吃有营养的食物");}//...public void show(){eat();  //省略了thisthis.eat();super.eat();    //父类中的eat()方法}
}

this.eat();直接在本类找,找到了,就直接调用本类的重写方法即可。

super.eat();直接在直接父类中找,找到了,就直接调用父类被重写的方法即可。

eat();是省略了this.,所以本质上也是调用本类中的方法,若本类中找不到,才会去父类中找。

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s1=new Student();//...s1.show();}
}

运行结果:

image.png


举例3

父类【Person.java】

package yuyi01;public class Person {//...public void doSport(){System.out.println("人运动");}
}

子类【Student.java】

package yuyi01;public class Student extends Person {//...public void show1(){doSport();}
}

此时子类中调用的doSport()毫无疑问是父类中的方法,因为子类中没有重写它。

这时候它的前缀是啥呢?

若在本类中调用方法,前缀都会省略this.。调用show1()方法的时候,它会在本类中找doSport()方法,找不到就会去父类中找。

此时本类中没有doSport()方法,就会去父类中找,找到并调用。若父类中还没有,就会继续往上找,直到Object,还没有找到就会报错了。

画个图看看:

image.png

此时Sutdent类里面没有重写doSport(),所以只有一个父类Person中的doSport()而已,只能调用它。

从结果上说this.doSport()super.doSport()一致;但是从过程上来说this.doSport()先从本类开始找,super.doSport()直接向直接父类中找。

【Student.java】

package yuyi01;public class Student extends Person {//...public void show1(){doSport();this.doSport();super.doSport();}
}

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s1=new Student();//...s1.show1();}
}

运行结果:

image.png

小结
  • 方法前面没有super.和this.
    • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
  • 方法前面有this.
    • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
  • 方法前面有super.
    • 从当前子类的直接父类找,如果没有,继续往上追溯

2、super调用属性

  • 如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
  • 如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
  • 如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问
举例1

暂且不考虑权限的事情。此时父类Person和子类Student中有同名的属性id

父类【 Person.java】

package yuyi01;public class Person {//属性String name;private int age;int id; //身份证号}

子类【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id; //学号}

若此时创建子类Student的对象,那么它拥有几个属性呢?和父类同名的属性会不会被干掉?

来Debug一下:

image.png

所以,属性没有方法那样有覆盖之说

属性不会覆盖,而方法可以覆盖。


举例2

既然有两个同名的属性,那么该如何区分它们呢?

此时将父类和子类中的属性id都赋值。

父类【 Person.java】

package yuyi01;public class Person {//属性String name;private int age;int id=1001; //身份证号}

在子类中写一个show2()方法,输出id的结果是什么呢?

子类【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号public void show2(){System.out.println(id); //?}
}

此时输出语句并没有报错,这里遵循一个就近原则

就和之前说的get方法一样,比如:

image.png

再比如:

image.png

当时解决办法是这样:

image.png

具体关于this的讲解在这一篇博客:https://blog.csdn.net/m0_55746113/article/details/134089173?spm=1001.2014.3001.5502


所以此时的id会就近找一个一样的,然后就找到了本类的id。

若想要父类中的id,就需要加一个super.

子类【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号public void show2(){System.out.println(id); 	//1002System.out.println(this.id); 	//1002System.out.println(super.id); 	//1001}
}

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s1=new Student();//...System.out.println();s1.show2();}
}

运行结果:

image.png

举例3

父类【Person.java】

package yuyi01;public class Person {//属性String name;//...
}

子类【Student.java】

package yuyi01;/*** ClassName: Student* Package: yuyi04* Description:** @Author 雨翼轻尘* @Create 2023/10/29 0029 16:40*/
public class Student extends Person {//属性String school;int id=1002; //学号//方法public void show3(){System.out.println(name);   //这样写就相当于省略了thisSystem.out.println(this.name);System.out.println(super.name);}
}

name先在当前类里面找,若没有找到,就去父类中找。

从结果上,三个输出值是一样的;但从过程上来说,name先找本类再找父类,super.name直接找父类。

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s1=new Student();s1.show3();}
}

输出结果:

image.png


加super与this,就是区分重名的属性,重写的方法。

若没有重名属性和重写的方法,this与super加不加无所谓,只不过一个本类找,一个直接父类找,过程上有区别,结果上没有区别。

若是父类中没有的属性(本类中有),用super直接父类中找是会报错的。

image.png

小结

总结:起点不同(就近原则)

  • 变量前面没有super.和this.
    • 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量
    • 如果不是局部变量,先从当前执行代码的本类去找成员变量
    • 如果从当前执行代码的本类中没有找到,会往上找父类声明的成员变量(权限修饰符允许在子类中访问的)
  • 变量前面有this.
    • 通过this找成员变量时,先从当前执行代码的本类去找成员变量
    • 如果从当前执行代码的本类中没有找到,会往上找父类声明的成员变量(权限修饰符允许在子类中访问的)
  • 变量前面super.
    • 通过super找成员变量,直接从当前执行代码的直接父类去找成员变量(权限修饰符允许在子类中访问的)
    • 如果直接父类没有,就去父类的父类中找(权限修饰符允许在子类中访问的)

特别说明:应该避免子类声明和父类重名的成员变量

3、super调用构造器

引入

为何要调用构造器?

比如在Student类里new了一个Student对象,可以通过s1调用属性、方法。

【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号}

若此时父类Person里面的name属性没有限制,那么在测试里面可以调用name属性。

image.png

这里我们知道内存中有name属性,才直接调用它。

可我们new的是Student,相当于调用的是Student的构造器,会加载Student的结构,那为啥还会加载父类的结构呢(为啥内存中有

name属性)?这里就涉及到super调用构造器的问题。

举例1

① 子类继承父类时,不会继承父类的构造器(构造器只有在同名的类里面才有)。只能通过“super(形参列表)”的方式调用父类指定的构造器。

父类【Person.java】

package yuyi01;public class Person {//属性String name;private int age;int id=1001; //身份证号//构造器public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public Person(String name, int age, int id) {this.name = name;this.age = age;this.id = id;}
}

子类【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号//测试super调用父类的构造器public Student(){}public Student(String name,int age){}
}

比如在子类中调用父类中的空参构造器:

image.png

举例2

父类【Person.java】

package yuyi01;public class Person {//构造器public Person() {System.out.println("Person()...");}
}

子类【Student.java】

package yuyi01;public class Student extends Person {//测试super调用父类的构造器public Student(){super();    //调用父类中空参的构造器System.out.println("Student()...");}
}

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s2=new Student();}
}

输出结果:

image.png

当我们调用子类构造器创建对象的时候,先调用父类构造器,输出Person()...,然后再输出Student()...。如下:

image.png

可以在子类构造器中调用父类的构造器,格式就是super(形参列表)。

举例3

② 规定:“super(形参列表)”,必须声明在构造器的首行。(和this很像)

如下:

image.png


③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器, 结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一。

比如:

image.png


④ 如果在子类构造器的首行既没有显示调用"this(形参列表)“,也没有显式调用"super(形参列表)”, 则子类此构造器默认调用"super()",即调用父类中空参的构造器。

父类【Person.java】

package yuyi01;public class Person {//构造器public Person() {System.out.println("Person()...");}}

子类【Student.java】

package yuyi01;public class Student extends Person {public Student(String name,int age){//没有显示调用父类中空参的构造器}
}

测试类【StudentTest.java】

package yuyi01;public class StudentTest {public static void main(String[] args) {Student s3=new Student("Tom",13);}
}

输出结果:

image.png


Student(String name,int age)构造器首行,并没有写this(形参列表),也没有写"super(形参列表)"。此时会默认是Super(),而且是空参的。

来Debug看一下:

image.png

进入构造器了,如下:

image.png

再下一步:

image.png

所以,在调Student构造器的时候,没有写this,也没有super语句,会默认父类空参构造器。

若此时将空参构造器注释掉,会发现子类中两个构造器都会报错。第一个是显示调用,但没有找到空参构造器,就会报错;第二个虽然没有显示调用谁,但是默认调用了空参构造器,也没有找到,所以也会报错。如下:

image.png


⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。 只能是这两种情况之一。

画个图瞅瞅:

image.png


⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“(若有n个就会形成一个环,递归了),则剩下的那个一定使用"super(形参列表)”(显示或者默认)。

子类中的任何一个构造器,都会直接或间接地调用父类的构造器。如下:

image.png

开发中常见错误:

如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有空参的构造器,则编译出错。

调用父类构造器不是为了造对象,造对象需要搭配new,调用父类构造器是为了初始化信息–比如将父类的属性、方法加载到内存中。

image.png


举例4

父类【Person.java】

package yuyi01;public class Person {//属性String name;private int age;int id=1001; //身份证号//方法public int getAge() {return age;}public void setAge(int age) {this.age = age;}//构造器public Person() {System.out.println("Person()...");}
}

子类【Student.java】

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号public Student(String name,int age){//没有显示调用父类中空参的构造器setAge(age);super.name=name;	//当前类里面没有name属性,这里super也可以写成this}
}

上面的写法很Low,若父类Person中有这样的构造器:

package yuyi01;public class Person {//属性String name;private int age;int id=1001; //身份证号//构造器public Person() {System.out.println("Person()...");}public Person(String name, int age) {this.name = name;this.age = age;}}

子类可以这样写:

package yuyi01;public class Student extends Person {//属性String school;int id=1002; //学号public Student(String name,int age){super(name,age);}
}

那么子类就可以直接调用父类中的构造器,如下:(若是没有写,调用的就是父类中的空参构造器Person()

image.png

以后声明子类构造器的时候,构造器的首行就可以调用父类指定的结构了。

4、总结

子类继承父类以后(super关键字使用的前提是基于继承),我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下)

super调用方法、属性

🗃️如何调用呢?

需要使用"super."的结构,表示调用父类的属性或方法。

一般情况下,我们可以考虑省略"super."的结构。

但是,如果出现子类重写了父类的方法子父类中出现了同名的属性时,则必须使用"super."的声明,显式地调用父类被重写的方法父类中声明的同名的属性

特别说明:应该避免子类声明和父类重名的成员变量(方法没法避开)

在阿里的开发规范等文档中都做出明确说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

super调用构造器

① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。

② 规定:“super(形参列表)”,必须声明在构造器的首行。

③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,
结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一。

④ 如果在子类构造器的首行既没有显示调用"this(形参列表)“,也没有显式调用"super(形参列表)”,
则子类此构造器默认调用"super()",即调用父类中空参的构造器。

⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。
只能是这两种情况之一。

⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“,
则剩下的那个一定使用"super(形参列表)”。

–> 我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器
正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载到内存中,供子类对象使用

情景举例1:

class A{}
class B extends A{}class Test{public static void main(String[] args){B b = new B();//A类和B类都是默认有一个无参构造,B类的默认无参构造中还会默认调用A类的默认无参构造//但是因为都是默认的,没有打印语句,看不出来}
}

情景举例2:

class A{A(){System.out.println("A类无参构造器");}
}
class B extends A{}
class Test{public static void main(String[] args){B b = new B();//A类显示声明一个无参构造,//B类默认有一个无参构造,//B类的默认无参构造中会默认调用A类的无参构造//可以看到会输出“A类无参构造器"}
}

情景举例3:

class A{A(){System.out.println("A类无参构造器");}
}
class B extends A{B(){System.out.println("B类无参构造器");}
}
class Test{public static void main(String[] args){B b = new B();//A类显示声明一个无参构造,//B类显示声明一个无参构造,        //B类的无参构造中虽然没有写super(),但是仍然会默认调用A类的无参构造//可以看到会输出“A类无参构造器"和"B类无参构造器")}
}

情景举例4:

class A{A(){System.out.println("A类无参构造器");}
}
class B extends A{B(){super();System.out.println("B类无参构造器");}
}
class Test{public static void main(String[] args){B b = new B();//A类显示声明一个无参构造,//B类显示声明一个无参构造,        //B类的无参构造中明确写了super(),表示调用A类的无参构造//可以看到会输出“A类无参构造器"和"B类无参构造器")}
}

情景举例5:

class A{A(int a){System.out.println("A类有参构造器");}
}
class B extends A{B(){System.out.println("B类无参构造器");}
}
class Test05{public static void main(String[] args){B b = new B();//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了//B类显示声明一个无参构造,        //B类的无参构造没有写super(...),表示默认调用A类的无参构造//编译报错,因为A类没有无参构造}
}

image.png

情景举例6:

class A{A(int a){System.out.println("A类有参构造器");}
}
class B extends A{B(){super();System.out.println("B类无参构造器");}
}
class Test06{public static void main(String[] args){B b = new B();//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了//B类显示声明一个无参构造,        //B类的无参构造明确写super(),表示调用A类的无参构造//编译报错,因为A类没有无参构造}
}

image.png

情景举例7:

class A{A(int a){System.out.println("A类有参构造器");}
}
class B extends A{B(int a){super(a);System.out.println("B类有参构造器");}
}
class Test07{public static void main(String[] args){B b = new B(10);//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了//B类显示声明一个有参构造,        //B类的有参构造明确写super(a),表示调用A类的有参构造//会打印“A类有参构造器"和"B类有参构造器"}
}

情景举例8:

class A{A(){System.out.println("A类无参构造器");}A(int a){System.out.println("A类有参构造器");}
}
class B extends A{B(){super();//可以省略,调用父类的无参构造System.out.println("B类无参构造器");}B(int a){super(a);//调用父类有参构造System.out.println("B类有参构造器");}
}
class Test8{public static void main(String[] args){B b1 = new B();B b2 = new B(10);}
}

(4)小结:this与super

1、this和super的意义

this:当前对象

  • 在构造器和非静态代码块中,表示正在new的对象
  • 在实例方法中,表示调用当前方法的对象

super:引用父类声明的成员

2、this和super的使用格式

  • this
    • this.成员变量:表示当前对象的某个成员变量,而不是局部变量
    • this.成员方法:表示当前对象的某个成员方法,完全可以省略this.
    • this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错
  • super
    • super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
    • super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
    • super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错

(5)练习

1、练习1

🌋题目描述

修改方法重写的练习2中定义的类Kids中employeed()方法,在该方法中调用父类ManKind的employeed()方法,
然后再输出"but Kids should study and no job."

【Kids.java】

package yuyi02;/*** ClassName: Kids* Package: yuyi05* Description:修改继承内容的练习1中定义的类Kids,在Kids中重新定义employeed()方法,覆盖父类ManKind中定义的employeed()方法,输出"Kids should study and no job."* @Author 雨翼轻尘* @Create 2023/10/30 0030 10:56*/
public class Kids extends Mankind { //父类中声明的属性和方法都被继承到子类了,构造器就不提了。后边提super关键字的时候会提到,在子类当中调用父类中的构造器private int yearOld;public int getYearOld() {return yearOld;}public void setYearOld(int yearOld) {this.yearOld = yearOld;}public void printAge(){System.out.println("I am "+yearOld+" years old");}@Overridepublic void employeed() {System.out.println("Kids should study and no job.");}//构造器public Kids(){}public Kids(int yearOld){this.yearOld=yearOld;}//把父类中的属性也做一个赋值,包括自己的属性public Kids(int sex, int salary,int yearOld){this.yearOld=yearOld;//sex、salary两个 属性是父类继承过来的,怎么给他们赋值?setSex(sex);setSalary(salary);}
}

【Mankind.java】

package yuyi02;/*** ClassName: Mankind* Package: yuyi05* Description:* (1)定义一个ManKind类,包括*    成员变量int sex和int salary;* - 方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);** - 方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。* @Author 雨翼轻尘* @Create 2023/10/30 0030 10:32*/
public class Mankind {//属性private int sex;private int salary;//方法public int getSex() {return sex;}public void setSex(int sex) {this.sex = sex;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public void manOrWoman(){if(sex==1){System.out.println("man");} else if (sex==0) {System.out.println("woman");}}public void employeed(){if(salary==0){System.out.println("no job");} else {System.out.println("job");}}//构造器public Mankind() {}public Mankind(int sex, int salary) {this.sex = sex;this.salary = salary;}
}

【KidsTest.java】

package yuyi02;/*** ClassName: KidsTest* Package: yuyi05* Description:*(3)定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。* @Author 雨翼轻尘* @Create 2023/10/30 0030 10:58*/
public class KidsTest {public static void main(String[] args) {Kids someKid=new Kids();someKid.setSex(1);someKid.setSalary(100);someKid.setYearOld(12);//Kids类自己声明的方法someKid.printAge();//来自于父类中声明的方法someKid.manOrWoman();someKid.employeed();//System.out.println("*************");someKid.employeed();}
}

🤺代码

【 Kids.java】

package yuyi02;/*** ClassName: Kids* Package: yuyi05* Description:修改方法重写的练习2中定义的类Kids中employeed()方法,在该方法中调用父类ManKind的employeed()方法,然后再输出"but Kids should study and no job."* @Author 雨翼轻尘* @Create 2023/11/4 0030 10:56*/
public class Kids extends Mankind { //父类中声明的属性和方法都被继承到子类了,构造器就不提了。后边提super关键字的时候会提到,在子类当中调用父类中的构造器//...@Overridepublic void employeed() {//在子类中调用父类中被重写的方法super.employeed();    //先去调用父类中的employeed()方法System.out.println("but Kids should study and no job.");}//...
}

【Mankind.java】

package yuyi02;public class Mankind {//...public void employeed(){if(salary==0){System.out.println("no job");} else {System.out.println("job");}}
}

【KidsTest.java】

package yuyi02;public class KidsTest {public static void main(String[] args) {//...Kids someKid=new Kids();someKid.employeed();}
}

👻输出结果

image.png

2、练习2

🌋题目描述

在Cylinder类中修改求表面积的方法findArea()和求体积的方法findVolume(),使用上super。

【Circle.java】

package yuyi03;/*** ClassName: Circle* Package: yuyi06* Description:** @Author 雨翼轻尘* @Create 2023/10/31 0031 10:07*/
public class Circle {//属性private double radius;  //半径//方法public void setRadius(double radius){this.radius=radius;}public double getRadius(){return radius;}//求圆的面积public double findArea(){return Math.PI*radius*radius;}//构造器public Circle(){radius=1;}
}

【Cylinder.java】

package yuyi03;/*** ClassName: Cylinder* Package: yuyi06* Description:*  圆柱类* @Author 雨翼轻尘* @Create 2023/10/31 0031 10:19*/
public class Cylinder extends Circle {//属性private double length;  //高//方法public void setLength(double length){this.length=length;}public double getLength(){return length;}//求圆柱的体积public double findVolume(){return Math.PI*getRadius()*getRadius()*getLength(); //底面积*高//return findArea()*getLength();    //错误的}//构造器public Cylinder(){length=1;}//求表面积@Overridepublic double findArea() {return Math.PI*getRadius()*getRadius()*2+2*Math.PI*getRadius()*getLength();}
}

【CylinderTest.java】

package yuyi03;/*** ClassName: CylinderTest* Package: yuyi06* Description:** @Author 雨翼轻尘* @Create 2023/10/31 0031 10:29*/
public class CylinderTest {public static void main(String[] args) {Cylinder cy=new Cylinder();cy.setRadius(2.3);cy.setLength(1.4);System.out.println("圆柱的体积为: "+cy.findVolume());System.out.println("圆柱的表面积为: "+cy.findArea());}
}

🤺代码

【Cylinder.java】

package yuyi03;public class Cylinder extends Circle {//...//求圆柱的体积public double findVolume(){//return Math.PI*getRadius()*getRadius()*getLength(); //底面积*高  正确的//return findArea()*getLength();    //错误的return super.findArea()*getLength();}//...//求表面积@Overridepublic double findArea() {return Math.PI*getRadius()*getRadius()*2+2*Math.PI*getRadius()*getLength();}
}

【Circle.java】

package yuyi03;public class Circle {//...//求圆的面积public double findArea(){return Math.PI*radius*radius;}
}

【CylinderTest.java】

package yuyi03;public class CylinderTest {public static void main(String[] args) {Cylinder cy=new Cylinder();cy.setRadius(2.3);cy.setLength(1.4);System.out.println("圆柱的体积为: "+cy.findVolume());System.out.println("圆柱的表面积为: "+cy.findArea());}
}

👻输出结果

image.png

3、练习3

🌋题目描述

①写一个名为Account的类模拟账户。该类的属性和方法如下图所示。

image.png

该类包括的属性:账号id,余额balance,年利率annualInterestRate;

包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest(),取款方法withdraw(),存款方法deposit()。

写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。

使用withdraw方法提款30000元,并打印余额。

再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。

提示:在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。

运行结果如图所示。

image.png

②创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。

在CheckAccount类中重写withdraw方法,其算法如下:

————————————————————————————————————————

如果(取款金额<账户余额),

可直接取款

如果(取款金额>账户余额),

计算需要透支的额度

判断可透支额overdraft是否足够支付本次透支需要,如果可以

将账户余额修改为0,冲减可透支金额

如果不可以

提示用户超过可透支额的限额

————————————————————————————————————————

要求:写一个用户程序测试CheckAccount类。

在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。

使用withdraw方法提款5000元,并打印账户余额和可透支额。

再使用withdraw方法提款18000元,并打印账户余额和可透支额。

再使用withdraw方法提款3000元,并打印账户余额和可透支额。

提示:

(1)子类CheckAccount的构造方法需要将从父类继承的3个属性和子类自己的属性全部初始化。

(2)父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw方法中需要修改它的值,因此应修改父类的balance属性,定义其为protected。

运行结果如下图所示。

image.png


🤺代码①

【Account.java】

package yuyi04;/*** ClassName: Account* Package: yuyi04* Description:** @Author 雨翼轻尘* @Create 2023/11/4 0004 8:29*/
public class Account {//属性private int id; //账户private double balance; //余额private double annualInterestRate;  //年利率//构造器public Account(int id,double balance,double annualInterestRate){//super();this.id=id;this.balance=balance;this.annualInterestRate=annualInterestRate;}//方法public void setId(int id) {this.id = id;}public void setBalance(double balance) {this.balance = balance;}public int getId() {return id;}public double getBalance() {return balance;}public void setAnnualInterestRate(double annualInterestRate) {this.annualInterestRate = annualInterestRate;}/*** 获取月利率* @return*/public double getMonthlyInterest(){return annualInterestRate / 12;}/*** 取钱曹操作* @param amount  要取的钱数*/public void withdraw(double amount){if(balance>=amount){balance-=amount;}else{System.out.println("余额不足!");}}/*** 存钱操作* @param amount 要存的额度*/public void deposit(double amount){if(amount>0){balance+=amount;}}
}

【AccountTest.java】

package yuyi04;/*** ClassName: AccountTest* Package: yuyi04* Description:* 写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。*   使用withdraw方法提款30000元,并打印余额。*   再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。* @Author 雨翼轻尘* @Create 2023/11/4 0004 10:46*/
public class AccountTest {public static void main(String[] args) {Account acct=new Account(1122,20000,0.045);acct.withdraw(30000);System.out.println("您的账户余额为:"+acct.getBalance());acct.withdraw(2500);acct.deposit(3000);System.out.println("您的账户余额为: "+acct.getBalance());System.out.println("月利率为: "+acct.getMonthlyInterest());}
}

👻运行结果①

image.png


🤺代码②

【Account.java】

package yuyi04;/*** ClassName: Account* Package: yuyi04* Description:** @Author 雨翼轻尘* @Create 2023/11/4 0004 8:29*/
public class Account {//属性private int id; //账户private double balance; //余额private double annualInterestRate;  //年利率//构造器public Account(int id,double balance,double annualInterestRate){//super();this.id=id;this.balance=balance;this.annualInterestRate=annualInterestRate;}//方法public void setId(int id) {this.id = id;}/*public void setBalance(double balance) {this.balance = balance;}*/public int getId() {return id;}public double getBalance() {return balance;}public void setAnnualInterestRate(double annualInterestRate) {this.annualInterestRate = annualInterestRate;}/*** 获取月利率* @return*/public double getMonthlyInterest(){return annualInterestRate / 12;}/*** 取钱曹操作* @param amount  要取的钱数*/public void withdraw(double amount){if(balance>=amount){balance-=amount;}else{System.out.println("余额不足!");}}/*** 存钱操作* @param amount 要存的额度*/public void deposit(double amount){if(amount>0){balance+=amount;}}
}

【CheckAccount.java】

package yuyi04;/*** ClassName: CheckAccount* Package: yuyi04* Description:*  创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。* @Author 雨翼轻尘* @Create 2023/11/4 0004 14:51*/
public class CheckAccount extends Account{//属性private double overdraft;   //可透支限额//方法public double getOverdraft() {return overdraft;}public void setOverdraft(double overdraft) {this.overdraft = overdraft;}//重写withdraw方法/*** 针对于可透支的账户的取钱操作* @param amount  要取的钱数*/public void withdraw(double amount){if(getBalance()>=amount){//错误的:(左右结果都是一个值,何来赋值一说)//getBalance()=getBalance()-amount;//正确的super.withdraw(amount); //super别去掉了,这里调用的是父类的withdraw方法} else if (getBalance()+overdraft>=amount) {overdraft-=amount-getBalance(); //可透支的限额剩余量super.withdraw(getBalance());   //把原本账户的钱取光}else{System.out.println("超过可透支限额");}}//构造器public CheckAccount(int id,double balance,double annualInterestRate){super(id,balance,annualInterestRate);}public CheckAccount(int id,double balance,double annualInterestRate,double overdraft){super(id,balance,annualInterestRate);this.overdraft=overdraft;}
}

【CheckAccountTest.java】

package yuyi04;/*** ClassName: CheckAccountTest* Package: yuyi04* Description:*  要求:写一个用户程序测试CheckAccount类。*  在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。**  使用withdraw方法提款5000元,并打印账户余额和可透支额。*  再使用withdraw方法提款18000元,并打印账户余额和可透支额。*  再使用withdraw方法提款3000元,并打印账户余额和可透支额。** @Author 雨翼轻尘* @Create 2023/11/4 0004 22:05*/
public class CheckAccountTest {public static void main(String[] args) {CheckAccount checkAccount=new CheckAccount(1122,20000,0.045,5000);checkAccount.withdraw(5000);System.out.println("您的账户余额为: "+checkAccount.getBalance());System.out.println("您的可透支额为: "+checkAccount.getOverdraft());checkAccount.withdraw(18000);System.out.println("您的账户余额为: "+checkAccount.getBalance());System.out.println("您的可透支额为: "+checkAccount.getOverdraft());checkAccount.withdraw(3000);System.out.println("您的账户余额为: "+checkAccount.getBalance());System.out.println("您的可透支额为: "+checkAccount.getOverdraft());}
}

👻输出结果

image.png

⚡注意

【注意一】

当我们写完第一问的时候,第二问写CHeckAccount继承于Account,就会报错。

如下:

image.png

这是为哈呢?

在声明一个类没有显示写构造器的时候,会默认有一个空参的构造器。任何一个构造器的首行,要么写this(形参列表),要么是super(形参列表)。若现在构造器也没有写,那就是默认super()。

而现在父类Account里面根本没有提供空参构造器,所以会报错。

image.png

有两种解决办法。

第一种是给父类提供空参的构造器:

package yuyi04;public class Account {//...//构造器//空参构造器public Account(){}public Account(int id,double balance,double annualInterestRate){//super();this.id=id;this.balance=balance;this.annualInterestRate=annualInterestRate;}
}

第二种可以直接调用有参的构造器:

image.png


【注意二】

CheckAccount类里面重写的withdraw方法。

package yuyi04;public class CheckAccount extends Account{//...//重写withdraw方法/*** 针对于可透支的账户的取钱操作* @param amount  要取的钱数*/public void withdraw(double amount){if(getBalance()>=amount){//错误的:(左右结果都是一个值,何来赋值一说)//getBalance()=getBalance()-amount;//正确的super.withdraw(amount); //super别去掉了,这里调用的是父类的withdraw方法} else if (getBalance()+overdraft>=amount) {overdraft-=amount-getBalance(); //可透支的限额剩余量super.withdraw(getBalance());   //把原本账户的钱取光}else{System.out.println("超过可透支限额");}}
}

这里很容易弄混:

image.png

【小Tips】

按住Ctrl+Shift+向上方向键:本行与上一行互换

【Super的使用】

①子类重写的方法里面,调用父类被重写的方法:

image.png

image.png

(6)面试题

1、第一题

如下代码输出结果是多少?

package com.atguigu05._super.interview;/*** 判断运行结果** @author 雨翼轻尘* @create 2023/11/5*/
public class Interview01 {public static void main(String[] args) {new A(new B());}
}class A {public A() {System.out.println("A");}public A(B b) {this();System.out.println("AB");}
}class B {public B() {System.out.println("B");}
}

最终输出结果是:

image.png

分析一下,看图:

image.png

2、第二题

如下代码输出结果是多少?

package com.atguigu05._super.interview;/*** 判断运行结果** @author 雨翼轻尘* @create 2023/11/5*/
public class Interview01 {public static void main(String[] args) {new A(new B());}
}class A {public A() {System.out.println("A");}public A(B b) {this();System.out.println("AB");}
}class B extends A{public B() {System.out.println("B");}
}

最终输出结果是:

image.png

分析一下,看图:

image.png

3、第三题

如下代码输出结果是多少?

package yuyi05;/*** @author 雨翼轻尘* @create 2023/11/5*/
public class Interview02{public static void main(String[] args) {Father f = new Father();Son s = new Son();System.out.println(f.getInfo());//atyuyiSystem.out.println(s.getInfo()); //atyuyis.test();//atyuyi atyuyiSystem.out.println("-----------------");s.setInfo("轻尘");System.out.println(f.getInfo());//atyuyiSystem.out.println(s.getInfo());//轻尘s.test(); //轻尘 轻尘}
}
class Father{private String info = "atyuyi";public void setInfo(String info){this.info = info;}public String getInfo(){return info;}
}
class Son extends Father{private String info = "雨翼轻尘";public void test(){System.out.println(this.getInfo());System.out.println(super.getInfo());}
}

最终输出结果是:

image.png

分析一下,看图:


image.png


image.png


image.png


image.png

4、第四题

如下代码输出结果是多少?

package yuyi05;/*** @author 雨翼轻尘* @create 2023/11/5*/
public class Interview02{public static void main(String[] args) {Father f = new Father();Son s = new Son();System.out.println(f.getInfo());//返回最近的info,即本类的"atyuyi"System.out.println(s.getInfo()); //返回最近的info,即本类的"雨翼轻尘"s.test();//“雨翼轻尘” atyuyiSystem.out.println("-----------------");s.setInfo("轻尘");System.out.println(f.getInfo());//atyuyiSystem.out.println(s.getInfo());//雨翼轻尘s.test(); //雨翼轻尘 轻尘}
}
class Father{private String info = "atyuyi";public void setInfo(String info){this.info = info;}public String getInfo(){return info;}
}
class Son extends Father{private String info = "雨翼轻尘";public void test(){System.out.println(this.getInfo());System.out.println(super.getInfo());}//重写public String getInfo(){return info;}
}

最终输出结果是:

image.png

分析一下,看图:


image.png


image.png

二、子类对象实例化全过程

(1)介绍

调用子类构造器去创建对象的时候,会直接或间接地调用父类地构造器。

整个过程其实可以理解为关于某个类的对象,在创建这个对象的过程当中是什么样的场景。
image.png

Dog dog = new Dog("小花","小红");

image.png

(2)举例

代码举例:

class Creature{ //生物类//声明属性、方法、构造器
}class Animal extends Creature{ //动物类}class Dog extends Animal{ //狗类}class DogTest{public static void main(String[] args){//子类对象DOg在实例化的过程当中整个过程是怎样的呢?Dog dog = new Dog();	//创建DOg的对象中,涉及到父类、父类的父类加载的过程?//通过dog调用属性、方法,只要是在Animal或Creature里面定义的属性、方法dog.xxx();dog.yyy = ...;}
}

image.png

  1. 从结果的角度来看:体现为类的继承性

当我们创建子类对象后,子类对象就获取了其父类(所有父类,包括直接父类、间接父类)中声明的所有的属性和方法,在权限允许的情况下,可以直接调用。

  1. 从过程的角度来看:(继承性它在内存层面是怎么保证它是能够调用的)

当我们通过子类的构造器创建对象时,子类的构造器一定会直接或间接地调用到其父类的构造器,而其父类的构造器同样会直接或间接地调用到其父类的构造器,…,直到调用了Object类中的构造器为止。

正因为我们调用过子类所有的父类的构造器,所以我们就会将父类中声明的属性、方法加载到内存中,供子类的对象使用

问题:在创建子类对象的过程中,一定会调用父类中的构造器吗? yes!
先有父类的加载,才有子类的加载

  1. 问题:创建子类的对象时,内存中到底有几个对象?
    就只有一个对象(只new了一次)!即为当前new后面构造器对应的类的对象。

①造对象–>new

②构造器–>初始化<init>


叨叨:
这一篇写累死我了,战线拉得很长,不过值得,有任何错误的地方欢迎指正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132827.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-tree中展示项换行展示

文章目录 效果如下所示&#xff1a;没有换行展示的效果修改样式换行之后的展示效果 想要了解el-tree使用的详情往下看代码和数据如下所示Vue代码中可能使用到的数据如下Vue的代码如下&#xff1a;没有换行展示的效果换行之后的展示效果样式调试 效果如下所示&#xff1a; 没有…

数据库的备份和恢复

备份&#xff1a;完全备份&#xff0c;增量备份 完全备份&#xff1a;将整个数据库完整的进行备份 增量备份&#xff1a;在完全备份基础的之上&#xff0c;对后续新增的内容进行备份 备份的需求 1生产环境中&#xff0c;数据的安全性至关重要&#xff0c;任何数据都可能产生非…

【计算机架构】程序指令计数 | 功耗计算 | 电力功耗 | 安德尔定律(Amdahl‘s Law)

0x00 程序的指令计数 程序的指令计数&#xff08;Instruction Count&#xff09;由程序本身、ISA&#xff08;指令集架构&#xff09;和编译器决定。这表示一个程序中包含的指令数量受到程序编写方式、计算机体系结构和编译器的影响。 每条指令的平均周期数&#xff08;Averag…

在云上jupylab(codelab)常用的shell命令

1、切换当前文件目录位置&#xff1a; %cd /project/train/ 2、删除目标文件夹和文件夹下面的内容&#xff0c;注意这个r是不能少的&#xff1a; !rm -r /project/train/src_repo/dataset 3、创建数据集相关文件夹 !mkdir /project/train/src_repo/dataset 4、复制指定…

想学计算机编程从什么学起?零基础如何自学计算机编程?中文编程开发语言工具箱之渐变标签组构件

想学计算机编程从什么学起&#xff1f;零基础如何自学计算机编程&#xff1f; 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件&#xff0c;…

linux硬盘挂载(linux 修改某个磁盘挂载到新目录\lvm扩容)

文章目录 一、什么是硬盘挂载二、linux 修改某个磁盘挂载到新目录三、Esxi下扩容硬盘1. 判断一个已有的文件系统是否使用了LVM(逻辑卷管理)2. 原本文件系统没有使用lvm&#xff0c;还可以lvm扩容吗&#xff1f;3. 原有文件系统使用lvm场景下扩容(lvm扩容)了解LVMEsxi LVM扩容步…

NOIP2000提高组第二轮T4:方格取数

题目链接 [NOIP2000 提高组] 方格取数 题目描述 设有 N N N \times N NN 的方格图 ( N ≤ 9 ) (N \le 9) (N≤9)&#xff0c;我们将其中的某些方格中填入正整数&#xff0c;而其他的方格中则放入数字 0 0 0。如下图所示&#xff08;见样例&#xff09;: 某人从图的左上…

ES 报错问题汇总

报错1&#xff1a; curl -XGET http://192.168.56.115:9200/_license解决方式 在 es/config/elasticsearch.yml文件,把开启密码验证把此处也修改成false xpack.security.enabled: false 报错2&#xff1a; 解决方式&#xff1a; 查看服务器es的license信息&#xff0c;发现 …

用「埋点」记录自己,不妄过一生

最近有朋友问我「埋点怎么做」&#xff0c;给朋友讲了一些互联网广告的案例&#xff0c;从源头的数据采集讲到末尾的应用分析和流量分配等&#xff08;此处省略N多字&#xff09; 解释完以后&#xff0c;我想到一个问题&#xff1a;有了埋点可以做分析&#xff0c;那我们对自己…

机器学习概论

一、机器学习概述 1、机器学习与人工智能、深度学习的关系 人工智能&#xff1a;机器展现的人类智能机器学习&#xff1a;计算机利用已有的数据(经验)&#xff0c;得出了某种模型&#xff0c;并利用此模型预测未来的一种方法。深度学习&#xff1a;实现机器学习的一种技术 2…

yum

什么是yum? Linux中我们也要进行工具/指令/程序&#xff0c;安装&#xff0c;检查卸载等&#xff0c;需要yum的软件 安装软件的方式&#xff1a; 1.源代码安装--交叉编译工作 2.rpm包直接安装 3.yum / apt-get yum:yum是我们linux预装的一个指令&#xff0c;搜索&#x…

【数据结构】顺序表和链表

顺序表和链表 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连…

uniapp 省市区三级联动选择器

还有半个小时下班&#xff0c;总想着发点光亮照耀他人。IT技术这东西&#xff0c;尤其是UI方面的东西&#xff0c;于用户体验至关重要&#xff0c;想想最近使用uni-data-picker的丑陋页面&#xff0c;自己重构了这个功能&#xff0c;新加实现&#xff0c;效果图如下&#xff0c…

SRC实战 | CORS跨资源共享漏洞

CORS跨资源共享 跨源资源共享 (CORS) 是一种浏览器机制&#xff0c;允许网页使用来自其他页面或域的资产和数据。 大多数站点需要使用资源和图像来运行它们的脚本。这些嵌入式资产存在安全风险&#xff0c;因为这些资产可能包含病毒或允许服务器访问黑客。 CORS响应头 CORS通…

类(class)

类是 C中一个非常重要的元素&#xff0c;可以说是 C的灵魂所在了&#xff0c;我们都知道 C说一种面向对象的编程语言&#xff0c;那么面向对象是一种什么概念呢&#xff1f;在 C程序设计中&#xff0c;所有一切东西都可以称之为对象&#xff0c;任何对象都应该具有属性和行为。…

C++基础——类与对象

1 概述 C是面向对象的语言&#xff0c;面向对象语言三大特性&#xff1a;封装、继承、多态。 C将万事万物抽象为对象&#xff0c;对象上有其属性和行为。 2 封装 2.1 封装的意义 封装是面向对象的三大特性之一&#xff0c;封装将属性和行为作为一个整体&#xff0c;对属性和…

灵活调整宣传策略,媒体发稿和新闻发布的优势所在

企业在当今信息爆炸的时代&#xff0c;要想在市场竞争中脱颖而出&#xff0c;提高公信力是至关重要的。而媒体发稿和新闻发布是提升企业公信力的重要手段之一。下面将从门户网站的权威展示、搜索引擎排名的提升、内容的持续稳定有效性、内容的可改性以及协助增加网站流量等方面…

浅谈自动化测试框架开发

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Linux中for循环

for do done 复习知识点&#xff1a;cut命令&#xff0c;id命令&#xff0c;finger命令&#xff0c;for循环 程序如上&#xff0c;-d 接分隔符&#xff0c;-f后的数字表示分隔后的列 从结果可以看出&#xff0c;系统上没有finger这个命令&#xff0c;后面会学到yum安装命令&a…

Python---字符串的修改方法---replace()替换

修改字符串&#xff0c;指的就是通过函数&#xff08;方法&#xff09;的形式修改字符串中的数据。 编号函数作用1replace()返回替换后的字符串2split()返回切割后的列表序列3capitalize()首字母大写4title()所有单词首字母大写5upper()与lower()返回全部大写或小写的字符串6l…