JAVA的面向对象(下)
类的继承(extends)
Java语言的继承采用的是单重继承。一个类只能有一个直接父类。父与子类的关系。
继承的语法格式:
访问修饰符[修饰符] class 类名 extends 父类名{
}
父类
class Employee{
private String name;
private int age;
private double salary =3000.0;
public Employee(String name,int age,double salary){
this.name=name;
this.age=age;
this.salary=salary;
}
public Employee(){
}
public double getSalary(){
return salary;
}
public double getMothlyIncome(){
return salary;
}
}
子类的继承
class Manager extends Employee{
private double bonus=1500.0
public Manager(){
}
public void setBonus(double bonus){
this.bonus=bonus;
}
public double getBonus(){
return bonus;
}
}
测试类
public class InheritanceTest{
public static void main(String[] args){
Manager manager=new Manager();
double sal=manager.getSalary();
System.out,println("月薪"+sal);
System.out,println("奖金"+manager.getBonus());
}
}
满足继承关系的两个类
1.子类拥有父类的所有属性。
2.子类拥有父类的所有方法。
3.子类不能拥有父类的构造方法。
4.父类不拥有子类所特有的属性和方法。
继承的优点:
1.可以创建更为特殊的了类型
2.可提高代码的重用性
3.可以提高程序的可维护性。
super关键字
在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句。
子类需要调用父类的某些方法。继承不继承父类的构造方法,而是子类的构造方法调用父类的构造方法。
语法:super([ 参数值列表])
surer关键字还可以调用父类中访问权限的属性和方法。特别是用于调用被覆盖的父类方法的情况。
格式:
调用本类中的构造方法
this(实参列表);
调用父类中的空参数构造方法
super();
调用父类中的有参数构造方法
super(实参列表);
public class Test {
public static void main(String[] args) {
new Zi();
}
}
class Fu{
int num ;
Fu(){
System.out.println("Fu构造方法"+num);
num = 4;
}
}
class Zi extends Fu{
Zi(){
//super(); 调用父类空参数构造方法
System.out.println("Zi构造方法"+num);
}
}
执行结果:
Fu构造方法0
Zi构造方法4
访问控制符
访问控制符的作用是说明被声明的内容的访问权限。
| public | protected | default | private |
同一类中 | √ | √ | √ | √ |
同一包中(子类与无关类) | √ | √ | √ |
|
不同包的子类 | √ | √ |
|
|
不同包中的无关类 | √ |
|
|
|
- 要想仅能在本类中访问使用private修饰;
- 要想本包中的类都可以访问不加修饰符即可;
- 要想本包中的类与其他包中的子类可以访问使用protected修饰
- 要想所有包中的所有类都可以访问使用public修饰。
- 注意:如果类用public修饰,则类名必须与文件名相同。一个文件中只能有一个public修饰的类。
static
static修饰的方法称类方法,也叫静态方法。没有用static叫实例方法。类方法和一般的成员方法也有所不同,类名直接引用。
静态方法:不能重写,都是引用父类
public static void staticMethod (){
System.out.println();
}
非静态方法:父类没有方法,是无法编译。
先看父类有没有这个方法,再看子类的方法有没有重写。
特点:
被static修饰的成员变量属于类,不属于这个类的某个对象。
被static 修饰的成员可以建议通过类名直接访问。
内容:优先于对象存在,只能访问静态,可以定义在任意类中。
好处:
1.只能通过规定方法访问数据
2.隐藏类的实现细节。
3.方便加入控制语句
4.方便修改实现。
类方法内部不能使用this,不能引用其他非静态成员。
静态初始化块。
JVM第一次加载到内存中时执行一次,以后不再被执行。
final关键字
final关键字是最终的最后的意思,可以用该关键字来修饰变量,方法和类。final修饰的元素是不可变的
final关键字也可以修饰方法,不能被覆盖,不能在子类中重写。
final的特点
- final修饰类不可以被继承,但是可以继承其他类。
class Yy {}
final class Fu extends Yy{} //可以继承Yy类
class Zi extends Fu{} //不能继承Fu类
final修饰的方法不可以被覆盖,但父类中没有被final修饰方法,子类覆盖后可以加final。
class Fu {
// final修饰的方法,不可以被覆盖,但可以继承使用
public final void method1(){}
public void method2(){}
}
class Zi extends Fu {
//重写method2方法
public final void method2(){}
}
- final修饰的变量称为常量,这些变量只能赋值一次。
final int i = 20;
i = 30; //赋值报错,final修饰的变量只能赋值一次
引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改
final Person p = new Person();
Person p2 = new Person();
p = p2; //final修饰的变量p,所记录的地址值不能改变
p.name = "小明";//可以更改p对象中name属性值
p不能为别的对象,而p对象中的name或age属性值可更改。
修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法的均需要为其赋值。)
class Demo {
//直接赋值
final int m = 100;
//final修饰的成员变量,需要在创建对象前赋值,否则报错。
final int n;
public Demo(){
//可以在创建对象时所调用的构造方法中,为变量n赋值
n = 2016;
}
}
多态:
在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法
父类类型 变量名=new 子类类型();
特点:1.调用多态对象时,调用的属性是父类的
2.调用多态的对象时,调用属性是父类的,(子类的属性,跟多态对象一点关系都没有,无法调用)
调用的方法是子类。
多态对象的方法
1.多态对象可以调用父类的方法
2.多态对象不能调用子类的方法(不是重写方法)
3.可以调用子类(重写父类方法)的方法
总结:多态对象调用的是重写的方法,如果没有就会向上找。
记:
针对类的属性:编译看左边,运行看左边(先看父类有没有,再看父类有没有)
针对类的方法:编译看左边,运行看右边(先看父类有没有,再看子类有没有)
把子类对象(或子类的对象变量)赋值给父类的对象变量的情况称为向上转型。
把父类的对象变量赋值给子类的对象变量的情况称为向下转型,向下转型不能自动进行,需要进行类型强制转换操作。
多态方法:
例子:
/**方法多态的例子*/
public class MethodPolymorphismTest{
public static void main}(String [] args){
Animal2 an=new Animal2("啥动物");
System.out.println(an.getBark());
Animal2 an2=new Animal2("小黑狗","黑色");
System.out.println(an2.getBark());
Animal2 an3=new Animal2("蓝猫","蓝色");
System.out.println(an3.getBark());
}
}
class Animal2{ //动物类
private String name;
public Animal2(String name){
this.name=name;
}
public String getName(){
return name;
}
public String getBark(){
return "叫声....";
}
}
class Cat2 extends Animal2{
private String eyesColor;
public Cat2(String n,String c){
super(n);
eyesColor=c;
}
@Override
public String getBark(){
return "(>^ω^<)喵";
}
}
class Dog2 extends Animal2{ //狗类继承动物类
private String furColor;
public Dog2(String n,String c){
super(n);
furColor=c;
}
@Override //覆盖方法
public String getBark(){ //获取猫的叫声
return "旺。。旺。。";
}
}
抽象类
子类 必须实现抽象类的抽象方法,否则无法继承。抽象类是无法实例化对象,抽象类实现多态。
抽象方法是指没有方法主体的方法声明。
public abstract double getPerimeter();
public abstract double getArea();
abstract class Shape{
public abstract double getPerimeter();
public abstract double getArea();
}
/**抽象类的定义*/
abstract double length;
private double width;
public Shape(int length,int width){
this.length=length;
this.width=width;
}
public double getLength(){
return this.length;
}
public double getWidth(){
return this.Width;
}
public abstract double getPerimeter();
public abstract double getArea();
}
接口
在Java语言中,是通过interface关键字来定义接口。
在接口中声明三个操作:
/**能飞的功能接口*/
public interface Flyer{
/**起飞*/
public void takeoff();
/**飞行*/
public void fly();
/**降落*/
void land();
}
一个接口中可以多个方法,这些方法不用public修饰也自动为public的。接口中所有方法都没有方法体,相当于接口中的所有方法都是抽象的。
注意:接口不是类,接口中不能定义构造器(方法)
接口就是用来被子类实现的,类的定义中采用implement关键字来实现接口。
/**飞行类实现飞行接口*/
class Airplane implement Flyer(){
public void takeoff(){
System.out.println("飞机加速直到起飞");
}
public void fly(){
System.out.println("");
}
public void land(){
System.out.println("");
}
}
接口可以用来声明变量,但接口不是类,不能用来创建对象。接口变量引用的是实现了该接口的子类的对象。
/**接口的定义及实现实例*/
public class InterfaceTest{
public static void main(String[] args){
Flyer f=new Airplane();//接口变量引用实现类Airplane的对象
f.takeoff();
f.land();
Flyer f2=new Bird();//接口变量引用实现类Airplane的对象
f2.takeoff();
f2.fly();
}
}
经常会把方法的参数类型定义成接口类型,而实际传入的值却用实现类的对象来代替,这样只需针对同一类型功能的参数定义一个方法,却可以适用于不同的实现类。
接口中的变量
接口中的变量全部都是public static fInal的,声明时就要赋值,以后也不能再更改了,这种变量也可以称为常量。
/**接口中的变量使用示例*/
public class InterfaceConstantTest{
public static void main(String [] args){
System.out.println(MathConstant.PI);
}
}
interface MathConstant{
public static final double E=2.718281828459045d;
double PI =3.1415926535d;
}
多重接口
一个类是可以同时实现多个接口的,多个接口之间用逗号分隔。
嵌套类
嵌套原因:
1.对象可以访问创建它的外部类的所有属性和方法;
2.通过在其外部类环境内的紧耦合嵌套声明,不为同一个包中的其他类所见,可支持更高层次的封装。
3,可以很方便地定义运行时回调。
4.在编写事件处理程序是很方便。
JAR文件
jar命令
JAR文件通过JDK提供的jar工具来制作的,jar工具就是位于JDK安装目录下bin子目录中的jar.exe
jar命令最常用的使用方式
jar cvf 要生成的jar文件名-C指定要归档的文件所在的目录名
jar cvfm 要生成的jar文件名清单文件名-C指定要归档的文件所在的目录名.