Java面向对象
- Java继承
Java通过extends关键字来声明一个类从另外一个类继承而来。
class 父类 { } class 子类 extends 父类 { }
示例:
//公共父类
public class Animal{
private String name;
private int id;
public Animal(String myName, int myid){
name = myName;
id = myid;
}
public void introduction(){
System.out.println("Hello,everyone! My name is " + id + "," + name +".");
}
}
//子类 public class Penguin extends Animal { public Penguin(String myName, int myid) { super(myName, myid); } } public class Mouse extends Animal { public Mouse(String myName, int myid) { super(myName, myid); } }
继承的特性:
-
子类拥有父类非private的属性,方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法。
-
Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
-
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。
继承关键字:
- extends关键字(单一继承,一个子类只能拥有一个父类)
- implements关键字(使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
//implements关键字示例 public interface A { public void eat(); public void sleep(); } public interface B { public void show(); } public class C implements A,B { }
- super 关键字(我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。) 如果调用super,必须写在子类构造方法的第一行。
- this 关键字(指向自己的引用)。
class SuperClass { int i = 50; } class SubClass extends SuperClass { int i =100; public void showMessage() { System.out.printf("super.i = %d, this.i = %d\n", super.i, this.i); } }
输出:
super.i = 50, this.i = 100
- Java中 this() 和 this. 的区别
- 代表当前类
public class Dog{
private String name;
private float age;
public steName(String name){
this.name = name;
}
这里的 this 就代表当前的这个Dog类。this.name 可以理解为 dog.name ,但不等于。
之所以要用 this.name = name; 这种语法。这是java所提倡的写法,如果你的方法参数与类属性名不同,this大可不必,但java提倡构造方法参数与类属性名相同的做法。
2.在构造函数中的使用
public class Dog{ private String name; private int age; //有一个参数的构造函数 public Dog(String name){ this.name = name; } public Dog(String name,int age){ this.name = name; this.age = age; } //这个无参构造方法里调用的有两个参数的构造方法,这个也就是this的第二种用法了! public Dog(){ this("nihao",20); } }
- final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
声明类:
final class 类名 {//类体}
声明方法:
修饰符(public,private,void,protected等) final 返回值类型 方法名(){//方法体}
- 构造器
子类不能继承父类的构造器(构造方法或者构造函数),但是父类的构造器带有参数的,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表。
如果父类有无参构造器,则在子类的构造器中用super调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。
- Java重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。
//TestDog.java class Animal{ public void move(){ System.out.println("Animal can move."); } } class Dog extends Animal{ public void move(){ System.out.println("Dog can move and run."); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 } }
方法的重写规则:
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
- super关键字的使用
当需要在子类中调用父类的被重写方法时,要使用super关键字。
//TestDog.java
class Animal{ public void move(){ System.out.println("Animal can move."); } } class Dog extends Animal{ public void move(){ super.move(); // 应用super类的方法 System.out.println("Dog can move and run."); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Dog 对象 b.move(); //执行 Dog类的方法 } }
输出:
Animal can move.
Dog can move and run.
- Java重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //以下两个参数类型顺序不同 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); } }
- Java多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态存在的三个必要条件:
- 继承
- 重写
- 父类引用指向子类对象
如:
Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
- 虚方法
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。
要想调用父类中被重写的方法,则必须使用关键字super。
- Java抽象类
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
在Java语言中使用abstract class来定义抽象类。
抽象类总结规定:
-
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
-
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
-
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
-
4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
-
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
- Java封装
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。
实现java封装的步骤:
- 修改属性的可见性来限制对属性的访问(一般限制为private)。
- 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问。
示例:
/* 文件名: EncapTest.java */ public class EncapTest{ private String name; private String idNum; private int age; public int getAge(){ return age; } public String getName(){ return name; } public String getIdNum(){ return idNum; } public void setAge( int newAge){ age = newAge; } //两种赋值方法 public void setName(String name){ this.name = name; } //采用this关键字是为了解决实例变量(private String name)和局部变量(String name)中name之间发生同名冲突。 public void setIdNum( String newId){ idNum = newId; } }
上述类变量是这么被访问的:
/* F文件名 : RunEncap.java */ public class RunEncap{ public static void main(String args[]){ EncapTest encap = new EncapTest(); encap.setName("James"); encap.setAge(20); encap.setIdNum("12343ms"); System.out.print("Name : " + encap.getName()+ " Age : "+ encap.getAge()); } }
- Java接口
接口(Interface),在Java编程语言中是一个抽象类型,是抽象方法和常量值的定义的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
接口定义举例:
public interface Runner{ int id = 1; public void start(); public void run(); public void stop(); }
接口特性:
- 多个无关的类可以实现同一个接口。
- 一个类可以实现多个无关接口。
- 与继承关系类系,接口与实现类之间存在多态性。
- 接口中声明属性默认为 public static final 的: 也只能是 public static final 的。
- 接口中只能定义抽象方法,而且这些方法默认为 public 的、也只能是 public 的。
- 接口可以继承其他的接口,并添加新的属性和抽象方法。