继承

什么是继承
继承是OOP面向对象编程三大特点之一: 1.封装 2. 继承 3. 多态
继承是面向对象软件技术当中的一个概念,与多态、封装共为面向对象的三个基本特征。继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。
继承(英语:inheritance)。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
如果某类B“继承”另某类A,就把这个B称为“A的子类或派生类(subclass)”,而把类A称为“B的父类”也可以称为“A是B的超类或基类(superclass)”。
为什么使用继承?

1.提高代码的可重用性
2.起到扩展功能的作用!
需求:动物园引进新品种 Dog,模拟 id age name 属性。动物园引进新的动物 Cat.同样有 id age name 属性忽然有一天,老板说id不好 要改名 aid 。两个动物很好改,如果有一万个动物,能改很麻烦,改完运行三个月后,老板又说了,还是id好,改回来!程序员们苦逼的改改改。又改完了,运行三个月后,老板又说了,还是aid好,再改回来!。。。程序员崩溃的!如果使用继承,这个问题就迎刃而解了,我们只需要将这些共同属性放在父类中,然后让其他动物来继承,改属性名,就直接在父类改就行了......
如何实现继承
语法:
public class 子类名 extends 父类名{
}
例子:

public class Person {
    //人的基本属性和行为
    String name;
    int age;
    public Person(){

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(age+"岁的"+ name+"在吃饭。。。");
    }
    public void seleep(){
        System.out.println(age+"岁的"+ name+"在睡觉。。。");
    }
}
public class Student extends Person{//学生继承人的基本属性和行为

    public static void main(String[] args) {
        Person person=new Person("小木",18);
        person.eat();
        person.seleep();
    }
}

方法的重写
听上去和方法的重载很相像,但是这两个是完全不一样的两个东西。
子类重写父类中的方法内容,重写的只是方法体的内容。
为什么出现方法的重写?
当父类的功能无法满足子类的需求时,子类可以重写父类中的方法。

Father{  

     smoke(){ //抽烟

           sout("抽的哈德门")

     }

}

Son exends Father{

      //儿子也要抽烟  但是父类抽的烟无法满足子类的要求。

      smoke(){

              sout("抽的为中华")

       }

}

Son s=new Son(); 
s.smoke();

重写的特点
1.子类中的方法名与父类中的方法名一致。

2.子类的方法参数要和父类的方法参数一致。

3.子类的方法的返回类型要和父类的方法的返回类型一致。

4.访问修饰符不能小于父类的。

super关键字
super表示父类对象,子类通过该对象可以调用父类被重写的方法。this表示本类对象
如果想调用父类中的方法。
父类:

public class Person {
    String name;
    int age;
    public Person(){

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(age+"岁的"+ name+"在吃饭。。。");
    }
    public void seleep(){
        System.out.println(age+"岁的"+ name+"在睡觉。。。");
    }
    public void introduced(){
        System.out.println("年龄:"+age+"\n名字:"+name);
    }
}

子类:

public class Student extends Person{
    public void introduced(){
        super.introduced();//调用父类内容
        System.out.println("是一名学生");//在父类方法的基础上加以补充....
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        Student student=new Student();
        student.age=18;
        student.name="小木";
        student.introduced();
    }
}

创建子类对象时构造方法的加载顺序
再调用子类对象的构造方法时,先执行父类的构造方法,再执行子类的构造方法。【先有爹再有儿子】

public class Test01 {
    public static void main(String[] args) {
        S s=new S();//调用对应类的构造方法
    }
}
class F{
    //表示父类的构造函数
     public F(int a){
         System.out.println("父类无参构造函数");
     }
}

class S extends F{
     public S(){
         super(15);//默认省略super()表示调用父类的无参构造方法,而且这句话必须放在子类构造方法的第一行代码;
                      //如果父类中没有定义无参构造函数,则子类构造方法会出现错误。 必须手动调用父类有参的构造函数
         System.out.println("儿子的构造函数");
     }
}

验证: 再初始化子类时,先初始化父类对象,再初始化子类对象。

案例:

public class Test {
    static {
        System.out.println("1. Test的静态代码");
    }
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println("6.主函数代码");
        Son son1 = new Son();
    }
}
class Father{
    public Father(){
        System.out.println("2.父类的构造方法");
    }
    static{
        System.out.println("3.父类的静态代码块");
    }
}
class Son extends Father{
    static {
        System.out.println("4.子类的静态代码块");
    }
    public Son(){
        System.out.println("5. 子类的构造方法");
    }
}
//1. 静态代码块--会随着类的加载而被加载而且只会被加载一次。
//2. 先在家父类得到构造方法再加载子类的构造方法。
//13425625.

零散的内容
java中只允许单继承。----一个类只能继承一个父类。

java允许多层继承。----->A extends B{} B extends C{}

final关键字
意思: 最终的。它可以修饰属性,方法,修饰类。

final如果修饰属性表示该属性为常量,其值不能改变,而且必须赋值。

final修饰方法表示该方法为最终方法,不允许子类重写该方法。

final修饰类表示该类为最终类,不允许子类继承。

public class Test01 {    
public static void main(String[] args) {
Teacher t=new Teacher();            
t.show();            
t.print();    
}
}//final修饰的类表示最终类,不能被子类继承。
final class People{     
public int age; //普通成员变量     
public final String name="刘德华"; //final修饰的属性为常量,必须赋值。而且该值不能改变     
public void show(){         
// name="张学友";//而且该值不能改变          
age=55;     }     
//final修饰了该方法,表示该方法不能被重写。     
public final void print(){         
System.out.println("~~~~~~~~~~~~~");     
}
}
class Teacher extends People{
//      
public void print(){
 //子类无法重写父类中使用final修饰的方法,但是它可以被子类继承。
////      }}

例如String类能否被其他类继承呢? 不能。
String类的内容不能改变--每次修改都会创建新的对象--而且指针指向新的对象。private final char value[];
因为String存放的字符串都放在一个字符数组中,而字符数组使用final修饰。
访问修饰符
类成员使用不同的访问修饰符,导致类中成员的访问范围不同。

public:公共的。表示当前工程下任意类都可以访问该修饰符修饰的成员。

protected: 保护的。 表示只允许当前类的子类以及当前类所在包的类访问。

default:默认。表示只允许同一个包下的类访问。

private:私有 表示只允许同一个类下的成员方法。

Object类
表示所有类的根类,直接或间接的继承了Object类。如果某个类没有显示的继承父类,则默认继承了Object类。
class Food extends Object {
//没有显示的继承任何类,默认继承了Object类
}
toString()方法
当打印一个类对象时,默认调用的就是toString方法。

思考: String类对象为什么打印时不是刚才地址效果。 而是打印的为字符串的内容。

原因: String类重写了Object中toString方法了。我们后期也可以定义类时重写toString方法。打印我们自己类的信息。。

package demo03;

import demo02.Animal;

public class Test {
    public static void main(String[] args) {
        Food f=new Food("红烧肉",25);
        System.out.println(f);
        System.out.println(f);//发现直接打印对象和通过对象调用toString效果一样
    }
}

class Food extends Object { //没有显示的继承任何类,默认继承了Object类

    private String name;
    private double price;

    public Food() {
    }

    public Food(String name, double price) {
        this.name = name;
        this.price = price;
    }

    //重写Object类中的toString方法
    @Override
    public String toString() {
        return "食物名:"+name+";价格:"+price;
    }
}

equals方法
可以比较两个对象的内容是否相同。默认比较的是两个对象的地址是否一致。

因为String类重写了equals方法,让其变为值的比较。 后期如果你想比较自己自定义类的对象的内容,也可以重写equals方法。

包装类
万事万物皆为对象。 我们的基本类型就不是对象。我们就为基本类型包装了对应的包装类,这些类可以操作基本类型的数据。
byte---->Byte类[操作byte数据类型 该类中封装很多方法]
short--->Short类
int----->Integer
long---->Long类
float--->Float
double---->Double
boolean---->Boolean
char------>Character
自动装箱
装箱: 把基本类转换为对应的包装类型。这个过程叫装箱。

自动装箱: 把基本类型自动转换为包装类型。

public class Test01 {
    public static void main(String[] args) {
        int a=10;//基本类型
        Integer b=a; //基本类型自动转为了包装类型--自动装箱。jdk1.5后出现。
        Integer c=new Integer(a);//手动把基本类型封装到包装类上。
    }
}

自动拆箱
拆箱: 把包装类型转换为对应的基本类型。这个过程叫拆箱。

public class Test01 {
    public static void main(String[] args) {
        int a=10;//基本类型
        Integer b=a; //基本类型自动转为了包装类型--自动装箱。jdk1.5后出现。
        Integer c=new Integer(a);//手动把基本类型封装到包装类上。

        int d=b; //把包装类型自动转换为基本类型--自动拆箱。jdk
    }
}

** 如何把一个字符串数字转换为整数。**

public class Test02 {
    public static void main(String[] args) {
        String str="123";
        //把上面的字符串转为为数字类型。
        int a=Integer.parseInt(str);
        int compare = Integer.compare(2, -2);//比较两个整数是否相同 如果相同返回0 否则返回为0
        System.out.println(compare);

    }
}

posted on 2024-08-31 09:58  小木不痞  阅读(7)  评论(0编辑  收藏  举报

导航