Java面向对象(高级篇):一

1.继承

1.1继承作为面向对象三大特征之一,其重要性不言而喻,在分享我自己对继承的学习之前,我们先引入一段代码

//定义一个Teacher类
class Teacher{
    
    
private String name;
private int age;

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;
}
}
//定义一个Student类
class Student{
    
    
private String name;
private int age;
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;
}
}
//大家不难发现,Teacher类中已经有name和age两个属性,然而Student类中又重新定义了一遍,浪费了空间,那有没有什么办法可以让Student类中不用定义,将Teacher中的内容保留到Student类中呢?

答案当然是有的,接下来就引入我们今天要将的继承

1.2继承的定义格式
class 父类{}
class 子类 extends 父类{}
那我们再来看一下改进后的代码:

//定义父类
class Teacher{
    
    
private String name;
private int age;
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;
}
}
//定义子类
class Student extends Teacher{
    
    
//不添加任何代码
}

public class ExtendsTest{
    
    
public static void main (String args[]){
    
    
Student student = new Student();//实例化子类对象
student.setName("zjd");// 调用父类方法
student.setAge(18);
System.out.println("姓名:"+student.Getname());
System.out.prinrln("年龄:"+student.Getage());
}
}

我们发现Student类中并没有任何代码,却可以调用父类的方法,这样的操作,就是我们的继承。
1.3继承的特点
①提高了代码的复用性
②提高了代码的可维护性
③多态的前提
1.4继承的缺点:
①增强了类和类之间的耦合性
②打破了封装性
1.5特点:
①单继承:只能有一个父类
②多层继承:父类也可以有父类

在这里插入图片描述
1.6注意事项:
①子类只能继承父类非私有的方法和属性
在这里插入图片描述

②子类不能继承父类的构造方法
③父子类成员变量同名问题 查找顺序:
1.子类的局部
2.子类的成员
3.父类的成员
4.报错
在这里插入图片描述

2.static关键字

2.1概述:
针对对象中,有共同属性的这种情况,java给我提供了一个关键字:static

public class Student{
    
    
//成员变量
 private String name;
 private int age;
 private String country;
 //构造方法
 public Student(){
    
    }
 public Student(String name,int age){
    
    
     this.name = name;
     this.age = age;
}
 public Student(String name,int age,String country)
     this.name = name;
     this.age = age;
     this.country = country;
}
//成员方法
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 getCountry() {
    
    
    return country;
}

public void setCountry(String country) {
    
    
    this.country = country;
}
public void shouInfo(){
    
    
    System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
}
//主方法
class StudentTest{
    
    
    public static void main(String[] args){
    
    
     Student student = new Student("dd",18,"china");
     Student student1 = new Student("tt",19"china");
     Student student2 = new Student("xb",20"china");
     student.shouInfo();
     student1.shouInfo();
     student2.shouInfo();
}
}
}

其实我们会发现,Student类new出来的三个对象的成员变量中国籍都是一样的,如果说,现在要创建一万个对象,难道还要去手打一万个相同的成员变量嘛,所以static关键字帮我们解决了问题:
2.2特点:
1.随着类的加载而加载
2.先于对象存在
3.被类的所有对象共享(判断是否使用static关键字的依据)
4.可以通过类名调用
我们继续采用刚才的代码:

//这里我展示部分的代码
class Student{
    
    
//我在类中把国籍前面加上static
private static String country;
//我在添加一个静态方法
public static void method(){
    
    
    System.out.println("静态方法");
}
//然后在StudentTest中,我们可以通过类名直接调用
Student.method();

看一下写好的主方法代码:
在这里插入图片描述
试运行结果:
在这里插入图片描述
2.3注意事项:
1.在静态方法中,this关键字不能使用
分析:静态方法随着类的加载而加载,先于对象创建而this表示的是当前类的对象,随着对象的产生而产生

class People {
    
    
    private int num;
    private static int num1;

    public void function() {
    
    
       // System.out.println(num);//隐式表示成员变量
        //System.out.println(this.num);//明确表示成员变量
        method2();
        method();
    }

    public static void method() {
    
    
        //System.out.println(num);//隐式表示成员变量
        //System.out.println(this.num);
        //System.out.println(num1);
        method2();
    }
    public static void method2(){
    
    
        System.out.println("method2");
    }
}

2.静态的方法只能访问静态的成员变量和成员方法
非静态方法可以调用静态的变量

public class PersonTest {
    
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person();
        //调用非静态
        System.out.println(p1.num);
        //调用静态
        System.out.println(Person.num1);//通过类调用
        System.out.println(p1.num1);//通过对象调用
    }
}
class Person{
    
    
    //非静态
    int num = 100;
    //静态
    static int num1 = 200;
}

2.4面试题:静态变量和成员变量的区别:
1.所属不同:静态变量属于类,而成员变量属于对象
2.位置不同:静态变量在方法区的静态区,而成员变量在堆内存
3.生命周期不同
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而创建,随着对象的消失而消失
4.使用方法不同
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象调用

扫描二维码关注公众号,回复: 12121413 查看本文章

3.代码块

3.1代码块的概述:
局部代码块:局部位置,用于限定变量的生命周期
构造代码块:在类中成员的位置,用{}括起来的代码
执行顺序:先于构造方法执行
作用:将多个构造方法共同的代码放在一起,对对象进行初始化
静态代码块:在类中成员的位置,用{}括起来的代码,并且有static关键字修饰
执行顺序:加载类的时候执行
作用:对类进行初始化操作
3.2代码展示:

public class CodeTest {
    
    
    //静态代码块
    static {
    
    
        System.out.println("static  code");
    }
    {
    
     //构造代码块
        int y = 200;
        System.out.println(y);
    }
    //构造方法
    public CodeTest(){
    
    
        System.out.println("CodeTest");
    }
    //构造有参方法
    public CodeTest(int a){
    
    
        System.out.println(a);
        System.out.println("CodeTest");
    }
    {
    
    //构造代码块
        int z =300;
        System.out.println(z);
    }
    //主方法
    public static void main(String[] args){
    
    
        {
    
      //局部代码块
            int x = 100;
            System.out.println(x);
        }
        System.out.println("_______________________");

        CodeTest codeTest = new CodeTest();
        CodeTest codeTest1 = new CodeTest();
    }
}

3.3面试题:静态代码块,构造代码块,构造方法三者的执行顺序?
首先,应该是静态代码块,其次是构造代码块(只要调用构造方法,构造代码块就要执行),最后是构造方法

class  Student{
    
    
    {
    
    
        System.out.println("构造代码块");
    }
    static {
    
    
        System.out.println("静态代码块");
    }
    public Student (){
    
    
        System.out.println("构造方法");
    }
}

public class CodeTest2 {
    
    
    static {
    
    
        System.out.println("CodeTest2静态代码块");
    }

    public static void main(String[] args) {
    
    
        System.out.println("main方法执行了");
       Student student = new Student();
       Student student2= new Student();
   }

}

结果如下:
在这里插入图片描述

4.super关键字

4.1super关键字的概述:
super关键字代表的是当前子类的父类对象
4.2super的用法:
1.访问成员变量:super.成员变量
2.访问构造方法:super(…)
3.访问成员方法:super.成员方法()

5.继承中父子类构造方法的关系

**1.**子类中所有的构造方法都默认的访问父类的无参构造方法
原因:因为继承的关系,子类对象可以使用父类对象非私有的属性和方法,所以在创建对象前,必须对父类的数据进行初始化(创建对象)
**2.**所有子类的构造方法第一句默认的都是super(…)
**3.**如果父类中没有无参构造方法,将无法创建子类对象
解决方案:
①:在父类中添加无参构造
②:同super关键字指定访问父类的有参构造
③: 子类可以通过this调用本类中的其他构造方法,但是被调用的构造方法必须手动调用父类的有参方法
4.this()和super()不能共存,都必须是构造方法中的第一句

public class FUzilei {
    
    
    public static void main(String[] args) {
    
    
    zi zi1 = new zi("tom");

    }
}
class Fu{
    
    
    public Fu(){
    
    
        System.out.println("F 无参构造");
    }
    public Fu(String name){
    
    
        System.out.println("Fu 有参构造");
    }
}
class zi extends  Fu{
    
    
    public zi(){
    
    
        super("dd");
        System.out.println("zi 无参构造");
    }
    public zi(String name){
    
    
        this();
        System.out.println("zi 有参构造");
    }

}

结果如下:
在这里插入图片描述

6.继承中成员方法的关系:

父子类方法同名问题的调用:
1.先在子类中找
2.子类找不到,再去父类中找
3.最后报错

7.方法重写

7.1方法的重写
子类和父类方法声明完全相同时,会发生方法的重写
7.2方法的重载
一个类中具有多个方法名相同,但是参数列表不同的情况,叫方法的重载
7.3重写的应用
可以重写父类的方法,使子类中即拥有父类中的方法,也可以有自己特有的方法
7.4注意事项
1.子类重写父类的方法,访问权限不能降低
2.父类的私有方法不能被重写
3.父类的静态方法重写,必须也用静态(他不是方法重写,但形式与重写相似)

public class fangfachongxie {
    
    
    public static void main(String[] args) {
    
    
        smartPhone smartPhone1 = new smartPhone();
        smartPhone1.call("dd");
        smartPhone1.play();
        smartPhone1.setMSG("tt");
    }
}
class Phone{
    
    
    public void call(String name){
    
    
        System.out.println("给"+name+"打电话");
    }
    public void setMSG(String name){
    
    
        System.out.println("给"+name+"发短信");
  }
}
class smartPhone extends Phone{
    
    
    public  void call(String name){
    
    
        System.out.println("给"+name+"打视频电话");
    }
    public  void play(){
    
    
        System.out.println("打游戏");
    }
}

运行结果如下:
在这里插入图片描述

8.final关键字

8.1final关键字
修饰类,方法,变量
8.2修饰类时
类不能被继承
8.3修饰方法
不能被重写
8.4修饰变量
基本数据类型:初始化后,不能改变
引用数据类型:引用数据类型的地址不能变,但是地址指向堆内存中的数据可以变的
8.5注意事项
1.被final修饰的变量,必须在构造方法执行完毕前被初始化。
2.只能被赋值一次。

public class Final {
    
    
    public static void main(String[] args) {
    
    
        Zi zi = new Zi();
        zi.method();
        System.out.println(zi.num);
    }
}
 class Fu{
    
    
    public final int num = 100;
    public  void method(){
    
    
        System.out.println("111");
    }
}
  class Zi extends Fu{
    
    
    public  void method(){
    
    
        System.out.println("222");
    }
}

结果如下:
在这里插入图片描述

9.多态

9.1概述
同一操作作用于不同对象,可以产生不同结果
9.2前提
1.继承
2.方法的重写
3.父类的引用指向子类对象
父类 father = new Son()

public class DuotaiTest {
    
    
    public static void main(String[] args) {
    
    
        pets p1 = new dogs();
        pets p2 = new cats();
        cats p3 = new cats();
        p1.voice();
        p2.voice();
        p3.voice();
    }
}
class pets{
    
    
    public  void voice(){
    
    
        System.out.println("发出叫声");
    }
}
class dogs extends pets{
    
    
    public  void voice(){
    
    
        System.out.println("汪");
    }
}
class cats extends  pets{
    
    
    public  void voice(){
    
    
        System.out.println("喵");
    }
}

9.3成员访问特点
成员变量:编译看父类,运行看父类
成员方法:编译看父类,运行看子类
构造方法
静态方法:编译看父类,运行看父类

public class DuotaiTest2 {
    
    
    public static void main(String[] args) {
    
    
        Fu fu = new Zi();
        Zi zi = (Zi) fu;
        zi.method();
        zi.method2();
        //System.out.println(fu.num);
        //System.out.println(fu.num2);
        fu.method();
        fu.method2();
        //fu.function();
       // fu.function2();
       // zi.function();
       // zi.function2();
    }
}
class  Fu{
    
    
    public int num = 10;
    public int num2 = 20;

    public  void method(){
    
    
        System.out.println("FU method");
    }
    public  void method2(){
    
    
        System.out.println("FU method2");
    }
    public static void function(){
    
    
        System.out.println("f1");
    }
    public static void function2(){
    
    
        System.out.println("f2");
    }
}
class Zi extends  Fu {
    
    
    public int num = 30;
    public int num3 = 40;

    public void method() {
    
    
        System.out.println("Zi method");
    }

    public void method2() {
    
    
        System.out.println("Zi method2");
    }
    public static void function(){
    
    
        System.out.println("z1");
    }
    public static void function2(){
    
    
        System.out.println("z2");
    }
}

9.4多态转换
向上转型: Fu fu = new Zi()
向下转型:Zi zi = (Zi) fu

猜你喜欢

转载自blog.csdn.net/zjdzka/article/details/109570430
今日推荐