一.类的三大特征
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
133.多态性
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.23.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; }}//奇瑞QQclass 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总收入: 50000001(3).实现接口 V.S. 继承类
①Java的继承是单继承的, 也就是一个类最多只能有一个父类, 这种单继承机制可保证类的纯洁性, 比C++中的多继承机制简洁. 但是不可否认, 对子类功能的扩展有一定影响. 所以实现接口可以看作是对继承的一种补充.
②继承是层级式的, 不太灵活. 这种结构修改某个类就会打破这种继承的平衡, 而接口就没有这样的麻烦, 因为他只针对实现接口的类才起作用. 所以, 实现接口可在不打破继承关系的前提下, 对某个类功能扩展, 非常灵活.
四.final关键字
final可以修饰变量或者方法,
(1).当不希望父类的某个方法被子类覆盖时, 可以用final关键字修饰;
(2).当不希望类的某个变量被修改, 可以用final关键字修饰;
(3).当不希望类被继承时, 可以用final关键字修饰.
(4).final修饰的变量又叫常量, 一般用xx_xx_xx来命名;
(5).final修饰的变量在定义时必须赋值, 并且以后不能再赋值.