java入门到精通(六)面向对象知识拓展

Java入门到精通(一)语言基础
Java入门到精通(二)流程控制
Java入门到精通(三)数组介绍
Java入门到精通(四)字符串
Java入门到精通(五)面向对象

1.类的封装

封装是所有的面向对象编程的核心思想,将对象的行为和属性封装起来,其载体就是类,类通常会对用户隐藏实现细节,这里举个例子就是:厨师做菜,他不可能把做菜的细节给你客户暴露,所以去饭店经常会看到非工作人员禁止进入。
下面我们封装一个厨师类、服务员类
由服务员向厨师通知要做的菜,而客户完全不用知道谁做菜、谁切菜、谁洗菜。客户并不能指定厨师去洗菜、也不知道厨师名字。这就是封装的思想。

class cook{
    String name;

    public cook() {
        this.name = "Tony";
    }

    private void wash(){
        System.out.println(this.name + "洗菜");
    }

    private void cut(){
        System.out.println(this.name + "切菜");
    }

    public void cooking(String dish){
        wash();
        cut();
        System.out.println(this.name + "正在做"+dish);
    }
}

class waiter{
    private cook cook = new cook();
    public void takeOrder(String dish){
        cook.cooking(dish);
        System.out.println("制作完成");//服务员上菜
    }
}
public class tuDemo{

    public static void main(String[] args) {
        cook cook = new cook();
        cook.cut();//这种的调用权限不够编译器会报错
        waiter waiter = new waiter();
        waiter.takeOrder("鱼香豆腐");
    }
}

2.类的继承

继承使整个程序的结构变得有一定的弹性,在程序中复用已经定义的类不仅可以减少软件开发的周期,还可以提高软件的可维护性、可拓展性。

class parents{
    void method_1(){
        System.out.println("method_1");
    }
    void mehtod_2(){
        System.out.println("method_2");
    }
    public void method_3(){
        System.out.println("method_3");
    }
}
public class tuDemo extends parents{
	//方法的重写
    @Override
    void method_1() {
        System.out.println("重写父类方法");
    }

    @Override
    public void method_3() {
        super.method_3();
    }

    public static void main(String[] args) {
        parents parents = new parents();
        parents.method_1();//父类对象调用其方法
        tuDemo tuDemo = new tuDemo();
        tuDemo.mehtod_2();//子类直接调用父类
        tuDemo.method_1();//调用重写方法
        
    }
}
//method_1
//method_2
//重写父类方法

如上代码method_3() 权限修饰符的范围父类----->子类只能由小到大。如果编译器默认添加一般和被重写方法的权限是一样的。

这里需要注意:java中一个类只能继承一个父类,到多线程后就会知道一个类GUI程序既要继承JFrame类,
又要继承Thread类,java根本办不到,所以就引用了接口的概念(Runnable接口)。

所有类的父类:Object类
注意:getClass、notify、notifyAll、wait等方法不能重写因为被final修饰的方法不能重写

public final void wait() throws InterruptedException {
        wait(0);
    }

super关键字的介绍可以查看文章(五)文章的首部有链接点开即可查看。
这里补充一下super在构造函数中必须在构造函数的其他代码之前,否则会报错。在实列化子类的对象时,java编译器会在子类的构造函数中自动调用父类的无参构造函数,但是有参的构造函数则需要借助super关键词调用。

类的多态

类的多态是指:一种实现,多种定义。重载和重写都体现类的多态性。多态就是用基类引用,引用不同的派生类对象,通过基类的引用变量调用同名覆盖方法,这个基类引用引用了那个派生类的对象,就会调用那个派生类对象重写的方法他的好处就是,在编写代码的时候,不用给每一个派生类提供相应的入口,而是用基类引用接受所有派生类对象,然后调用同名覆盖方法。

简单说:父类引用调用子类对象,同一操作作用于不同对象,这就多态

什么是重载?什么是重写?
重载:与类中的方法名一样,参数列表不同。
重写:对父类的方法重写,重新编写方法中的具体实现,更改成员方法的权限,修改成员方法的返回值类型。

public int add(int a,int b){
	return a + b;
}
public int add(int a,float b){
	return a + b;
}

以上就是方法的重载。
向上转型:就是把子类对象赋值给父类变量,也就是说由较具体的类向抽象的类的转换。
向下转型:把父类变量赋值给子类变量,也就是说抽象类向具体的类的转化。
例如:可以说平行四边形是四边形,但不能说四边形是平行四边形。这种转换一般比较安全。

//这个列子来自于书上
class Quadrangle{

    public static void draw(Quadrangle q){

    }
}
public class Parallelogrm extends Quadrangle{
    int edge = 4;
    public static void main(String[] args) {
        Quadrangle quadrangle = new Quadrangle();
        draw(quadrangle);
        //向上转型
        Quadrangle quadrangle1 = new Parallelogrm();
        //父类对象无法访问子类独有的属性和方法
//        quadrangle1.edge = 6;
        draw(quadrangle);
        //这种则是向下转化,这种操作编译器直接会报错
        Parallelogrm parallelogrm = quadrangle;
        //向下转型必须显示的强制转换
        Parallelogrm parallelogrm = (Parallelogrm)quadrangle;
    }
}

一下来写一个抽象动物类,以及猫、猪、狗、鸟类对动物类的具体实现。他们都有叫的行为、但是鸟可以飞。这里就引用了多态的思想

interface IAniaml{//接口里面一般都是静态//pulic static final
    int DATA = 10;
    void fly();
}

abstract class Animal{   //拥有抽象方法的类,必须是一个抽象类
    protected String name;

    public Animal(String name){
        this.name = name;
    }

    public abstract void bark();
}

class  Cat extends Animal{

    public Cat(String name) {
        super(name);
    }

    @Override
    public void bark() {
        System.out.println(name +" maio miao!");
    }
}

class pig extends Animal{

    public pig(String name) {
        super(name);
    }

    @Override
    public void bark() {
        System.out.println(name+"heng heng");
    }
}

class dog extends  Animal{

    public dog(String name) {
        super(name);
    }

    @Override
    public void bark() {
        System.out.println(name +"wang wang");
    }
}

class bride extends Animal implements IAniaml{

    public bride(String name) {
        super(name);
    }

    @Override
    public void bark() {
        System.out.println(name+"jiji");
    }

    @Override
    public void fly() {
        System.out.println(name+"fly!");
    }
}

public class mass {

    public static void show(Animal animal){//传递的是父类引用子类对象
        animal.bark();

        //如果是鸟的可以高飞一下
        //判断某个对象是否是某个类的实列  引用形式如下:引用名 instanceof 类名(接口名)返回一个boolen
        if (animal instanceof IAniaml){
            ((IAniaml) animal).fly();
        }
    }

    public static void main(String[] args) {
        show(new Cat("加菲猫"));
        show( new dog("哈皮"));
        show(new pig("佩奇"));
        show(new bride("百灵鸟"));
    }
}

 这里介绍一下instanceof关键词:可以判断一个类是否实现了某个接口、或者某个实列是否属于某个类。

抽象类

abstract class Animal

一般将父类设置为抽象类,这里需要注意父类不能实列化对象
抽象方法是直接以分号结尾的,它没有方法体,抽象方法本身没有什么意义,除非他被重写。(因为父类不能实列化对象)

  1. 在抽象类中,可以有抽象方法,也可以有非抽象方法,但是包含了抽象方法的类一定是抽象了。
  2. 抽象类不能实列化对象。
  3. 当抽象类被继承之后,子类要重写所有的抽象方法。
  4. 如果继承抽象类的子类被定义抽象类,子类可以不用全部重写父类中的方法。
    接口:其实就是特殊的抽象类
interface IAniaml//interface声明接口
class bride extends Animal implements IAniaml//implement实现接口

接口中的方法全部是抽象方法,所以实现接口必须重写接口中的全部方法,接口中变量默认是static和final的,因此定义变量时必须对其进行初始化(常量)。
接口与抽象类的区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。

static关键词
声明的方法、变量都直接是类名.方法(变量)
static声明的变量可以叫共享变量
所有对象作用于同一变量。

public class Demo {
    static int i = 0;
    public int add(){
        return ++i;
    }
    public int lose(){
        return --i;
    }

    public static void main(String[] args) {
        Demo demo = new Demo();
        Demo demo1 = new Demo();
        System.out.println(demo.add());
        System.out.println(demo1.add());
        System.out.println(Demo.i);
        System.out.println(demo.lose());
        System.out.println(Demo.i);
    }
}
//1
//2
//2
//1
//1
public final static PI = 3.14;//常量,不能对其进行重新赋值
以下介绍一下静态代码块、代码块、构造方法的执行顺序。
public class DeriveTest {
    public static void main(String[] args) {
        B b1 = new B();
        B b2 = new B(); //

        b1.test();
    }
}

class A{
    protected int a;

    static{
        System.out.println("A static block init.");
    }

    {
        System.out.println("A instance block init.");
    }

    public A(){
        System.out.println("A()");
        this.a = 0;
    }

    public A(int a){
        System.out.println("A(int)");
        this.a = a;
    }

    public void show(){
        System.out.println("A.show a:" + a);
    }
}

class B extends A{
    private int b;
    private int a;

    static{
        System.out.println("B static block init.");
    }

    {
        System.out.println("B instance block init.");
    }

    public B(){
        // 如何在派生类中调用基类的构造函数呢?
        super(); // A()  a = 0
        System.out.println("B()");
    }

    public B(int data){
        super(data); // A(int) a = data
        System.out.println("B(int)");
    }

    public void show(){ // 作用域不同   show   A.show   a  A.a
        System.out.println("B.show a:" + super.a);
    }

    void test(){ // 测试方法
        // 在派生类中,调用基类的方法
        super.show();
    }
}
/*
A static block init.
B static block init.
A instance block init.
A()
B instance block init.
B()
A instance block init.
A()
B instance block init.
B()
A.show a:0
*/

由以上的执行结果可以看出先执行父类静态代码块,其次是子类静态代码块(静态代码块执行一次),之后顺序依次是、父类代码块、父类构造方法、子类代码块、子类构造方法。

final关键词介绍

  • 当final修饰变量时,被修饰的变量必须被初始化(赋值),且后续不能修改其值,实质上是常量;
  • 当final修饰方法时,被修饰的方法无法被所在类的子类重写(覆写);
  • 当final修饰类时,被修饰的类不能被继承,并且final类中的所有成员方法都会被隐式地指定为final方法,但成员变量则不会变。

内容整理的有欠缺后期会补上,实在写不动了。
希望大家点个赞~

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值