zoukankan      html  css  js  c++  java
  • Java学习第三篇:类的三大特征,抽象类,接口,final关键字

    一.类的三大特征

    1.封装性

    (1).什么是封装

    封装就是把抽象出的数据和对数据的操作封装在一起, 数据被保护在内部, 程序的其他部分只有通过被授权的操作(成员方法), 才能对数据进行操作.

    (2).访问控制修饰符

    Java中提供了四种访问控制修饰符号控制方法和变量的访问权限:

    (3).包

    问题的提出:假设现在有两个程序员共同开发一个项目, 程序员xiaoming希望定义一个类取名为Dog, 程序员xiaoqiang也想定义一个类也叫Dog. 该怎么办呢? (因为同一个包中不能有相同的类)

    ①包的作用

    区分相同名字的类; 当类很多时, 可以很好的管理类; 控制访问范围.

    ②包的命名规范

    小写字母, 比如com.sina.shunran

    ③包的打包命令

    package 包名, 比如package com.sina.shunran

    ④包的引入命令

    import 包名, 比如import java.awt.*;

    因此, 上面提出的问题的解决方法就是定义两个包, 然后在各自包下定义Dog类即可.

    (4).简单的程序实例

    下面给出(3)中所提出问题的解决方案.

    首先, 创建的文件目录如下(创建了两个包com.xiaoming和com.xiaoqiang, 以及两个文件Demo7.java, Dog.java)

    Dog.java的代码:

    package com.xiaoqiang;
    public class Dog {
        public void eat() {
            System.out.println("小狗吃骨头");
        }
    }

    Demo7.java的代码:

    package com.xiaoming;
    //引包
    import com.xiaoqiang.*;
    public class Demo7 {
        public static void main(String[] args) {
            //com.xiaoqiang中的Dog类
            com.xiaoqiang.Dog dog1=new com.xiaoqiang.Dog();
            dog1.eat();
            //com.xiaoming中的Dog类
            com.xiaoming.Dog dog2=new com.xiaoming.Dog();
            dog2.cry();
        }
    }
    
    class Dog {
        public void cry() {
            System.out.println("小狗叫");
        }
    }

    运行结果:

    小狗吃骨头
    小狗叫

    2.继承性

    继承可以解决代码复用, 当多个类存在相同的属性和方法时, 可以从这些类中抽象出父类, 在父类中定义这些属性和方法, 所有子类不需要重新定义这些属性和方法, 只需要通过extends语句来声明继承父类.

    (1).父类的哪些属性, 方法被子类继承了?

    (2).子类最多只能继承一个父类; Java中所有类都是Object类的子类;

    (3).简单的程序实例

    public class Demo8 {
        public static void main(String[] args) {
            B obj=new B();
            System.out.println(obj.a0);
            System.out.println(obj.a1);
            System.out.println(obj.a3);
        }
    }
    
    class A {
        int a0=0;
        public int a1=1;
        private int a2=2;
        protected int a3=3;
    }
    
    class B extends A {
        
    }

    运行结果:

    0
    1
    3

    3.多态性

    3.1.方法重载

    (1).方法重载的注意事项

    ①方法重载指的是同一个类中的方法重载, 方法名要相同;

    ②方法的参数类型, 参数个数, 顺序至少有一项不同;

    ③方法的返回类型可以不同;

    ④如果只是返回类型不一样,是不能构成重载的;

    ⑤如果只是控制访问修饰符不一样,是不能构成重载的.

    (2).简单的程序实例

    public class Demo9 {
        public static void main(String[] args) {
            ABC obj=new ABC();
            System.out.println(obj.getMax(12, 10));
            System.out.println(obj.getMax(12.2f, 10.3f));
        }
    }
    
    //如果只是返回类型不一样,是不能构成重载的
    //如果只是控制访问修饰符不一样,是不能构成重载的
    class ABC{
        public int getMax(int a,int b){
            return a>=b ? a : b;
        }
        public float getMax(float a,float b){
            return a>=b ? a : b;
        }
    }

    运行结果:

    12
    12.2

    3.2.方法覆盖

    (1).方法覆盖的注意事项

    ①方法覆盖指的是子类对父类中的方法的覆盖;

    ②子类的方法的返回类型, 参数, 方法名称要和父类方法的返回类型, 参数, 方法名称完全一样;

    ③子类方法不能缩小父类方法的访问权限.

    (2).简单的程序实例

    public class Demo10 {
        public static void main(String[] args) {
            Pig pig=new Pig();
            pig.cry();
            
            Dog dog=new Dog();
            dog.cry();
        }
    }
    
    class Animal{
        public void cry(){
            System.out.println("不知道怎么叫唤");
        }
    }
    
    class Pig extends Animal{
        //@override
        public void cry() {
            System.out.println("猪叫");
        }
    }
    
    class Dog extends Animal{
        //@override
        public void cry() {
            System.out.println("狗叫");
        }
    }

    运行结果:

    猪叫
    狗叫

    3.3.多态性

    所谓多态, 就是指一个引用在不同情况下的多种状态. 多态是指通过指向父类的指针, 来调用在不同子类中实现的方法.

    public class Demo11 {
        public static void main(String[] args) {
            Master m1=new Master();
            m1.feed(new Anim(), new Food());
            System.out.println();
            
            m1.feed(new Ca(), new Fish());
            System.out.println();
            
            m1.feed(new Do(), new Bone());
            System.out.println();
        }
    }
    
    //父类
    class Anim {
        public void eat() {
            System.out.print("动物吃");
        }
    }
    //子类
    class Ca extends Anim {
        public void eat() {
            System.out.print("猫吃");
        }
    }
    //子类
    class Do extends Anim {
        public void eat() {
            System.out.print("狗吃");
        }
    }
    //父类
    class Food {
        public void showName() {
            System.out.print("食物");
        }
    }
    //子类
    class Fish extends Food {
        public void showName() {
            System.out.print("鱼");
        }
    }
    //子类
    class Bone extends Food {
        public void showName() {
            System.out.print("骨头");
        }
    }
    
    class Master {
        public void feed(Anim an, Food fo){
            an.eat();
            fo.showName();
        }
    }

    运行结果:

    动物吃食物
    猫吃鱼
    狗吃骨头

    二.抽象类

    (1).抽象类的注意事项

    ①当父类的一些方法不能确定时, 可以用abstract关键字来修饰该方法(抽象方法), 用abstract来修饰该类(抽象类);

    ②抽象类是不可以实例化的.

    ③用abstract关键字来修饰一个类时, 这个类叫抽象类;

    ④用abstract关键字来修饰一个方法时, 这个方法叫抽象方法;

    (2).简单的程序实例

    public class Demo12 {
        public static void main(String[] args) {
            Ostrich obj=new Ostrich();
            obj.showName();
        }
    }
    
    //抽象类
    abstract class Bird {
        String name;
        int age;
        //抽象方法
        abstract public void showName();
    }
    
    class Ostrich extends Bird {
        //@Override
        public void showName() {
            System.out.println("鸵鸟");
        }
    }

    运行结果:

    鸵鸟

    三.接口

    接口就是给出一些没有内容的方法, 封装到一起, 到某个类要使用的时候, 再根据具体情况把这些方法写出来. 语法如下

    (1).接口的注意事项

    ①接口不能被实例化;

    ②接口中的所有方法不能有方法体;

    ③一个类可以实现多个接口;

    ④接口中可以有变量, 但变量不能用private和protected修饰;

    接口中的变量本质都是static的, 不管加不加static修饰;

    ⑥在Java开发中, 我们经常把常用的变量, 定义在接口中, 作为全局变量使用, 访问形式为 接口名.变量名;

    ⑦一个接口不能继承其他的类, 但是可以继承别的接口.

    (2).简单的程序实例

    public class Demo13 {
        public static void main(String[] args) {
            //计算汽车销售总收入
            CarShop carShop=new CarShop();
            carShop.sellCar(new BMW());
            carShop.sellCar(new CheryQQ());
            System.out.println("总收入: "+carShop.getMoney());
            //输出全局变量
            System.out.println(Car.var);
        }
    }
    
    //汽车接口
    interface Car {
        //汽车名称
        public String getName();
        //汽车售价
        public int getPrice();
        //声明一个全局变量
        int var=1;
    }
    
    //宝马
    class BMW implements Car {
        //@Override
        public String getName() {
            return "BMW";
        }    
        //@Override
        public int getPrice() {
            return 3000000;
        }
    }
    
    //奇瑞QQ
    class CheryQQ implements Car {
        //@Override
        public String getName() {
            return "CheryQQ";
        }
        //@Override
        public int getPrice() {
            return 2000000;
        }
    }
    
    //汽车出售店
    class CarShop {
        //售车收入
        private int money=0;
        //卖出一部车
        public void sellCar(Car car) {
            System.out.println("车型: "+car.getName()+
                               "单价: "+car.getPrice());
            money+=car.getPrice();
        }
        //售车总收入
        public int getMoney() {
            return money;
        }
    }

    运行结果:

    车型: BMW单价: 3000000
    车型: CheryQQ单价: 2000000
    总收入: 5000000
    1

    (3).实现接口 V.S. 继承类

    ①Java的继承是单继承的, 也就是一个类最多只能有一个父类, 这种单继承机制可保证类的纯洁性, 比C++中的多继承机制简洁. 但是不可否认, 对子类功能的扩展有一定影响. 所以实现接口可以看作是对继承的一种补充.

    ②继承是层级式的, 不太灵活. 这种结构修改某个类就会打破这种继承的平衡, 而接口就没有这样的麻烦, 因为他只针对实现接口的类才起作用. 所以, 实现接口可在不打破继承关系的前提下, 对某个类功能扩展, 非常灵活.

    四.final关键字

    final可以修饰变量或者方法,

    (1).当不希望父类的某个方法被子类覆盖时, 可以用final关键字修饰;

    (2).当不希望类的某个变量被修改, 可以用final关键字修饰;

    (3).当不希望类被继承时, 可以用final关键字修饰.

    (4).final修饰的变量又叫常量, 一般用xx_xx_xx来命名;

    (5).final修饰的变量在定义时必须赋值, 并且以后不能再赋值.

  • 相关阅读:
    Javascript 箭头函数2
    熊二周刊--20160911
    递归
    函数
    Python基本的数据类型内置方法(2)
    python 基础知识条件和循环
    Python初识_基本的数据类型
    计算机网络基础知识
    Python初识
    计算机基础-操作系统
  • 原文地址:https://www.cnblogs.com/shunran/p/3437206.html
Copyright © 2011-2022 走看看