Java面向对象部分总结
1、方法
方法是解决一类问题的步骤的有序组合、方法包含于类或对象中、方法在程序中被创建,在其他地方被引用。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主程序
int i = 1;
int j = 2;
int k = max(i,j); //调用方法
System.out.println(" 最大值是:" + k);
}
public static int max(int num1,int num2) { //方法
int result;
if(num1>num2)
result = num1;
else
result = num2;
return result;
}
}
2、可变参数
例:
package Test_hello;
public class Hello {
public static void main(String[] args) {
printMax(34,3,3,2,56.5);
printMax(new double[] {1,2,3});
}
public static void printMax(double... numbers) { //方法,使用可变参数
if(numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for(int i = 1; i<numbers.length;i++) {
if(numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
3、继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
类的继承格式:
class 父类 {
}
class 子类 extends 父类 {
}
继承的特性:
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承可以使用 extends 和 implements 这两个关键字来实现继承
extends关键字:
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类。
extends 只能继承一个类。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
Rectangle Rect = new Rectangle(); //实例化
int area;
Rect.setwidth(3);
Rect.setheight(2);
area = Rect.getArea();
System.out.println("area:"+area);
}
}
class Shape{ //父类,注意不能再有public关键字
protected int width;
protected int height;
public void setwidth(int w) { //方法1
width = w;
}
public void setheight(int h) { //方法2
height = h;
}
}
class Rectangle extends Shape{ //继承
public int getArea() { //方法
return (width * height); //注意只能继承父类非 private 的属性
}
}
implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
例:
class A { //父类1
public void eat();
public void sleep();
}
class B { //父类2
public void show();
}
class C implements A,B { //同时继承A、B父类
public void test();
}
super 与 this 关键字
super关键字:可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类(包括方法和属性)。
this关键字:指向自己的引用(包括方法和属性)。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
Animal a = new Animal(); //实例化
a.eat();
Dog d = new Dog(); //实例化
d.eatTest();
}
}
class Animal{ //父类
void eat() { //方法
System.out.println("animal:eat");
}
}
class Dog extends Animal{ //继承
void eat() { //方法
System.out.println("Dog:eat");
}
void eatTest() { //方法
this.eat(); //this 调用自己的方法
super.eat(); //super 调用父类的方法
}
}
结果:
animal : eat
dog : eat
animal : eat
final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
final class Animal { } //声明类:
public final int eat() { } //声明方法
构造器
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) {
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClas2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
输出:
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
4、继承之重写(Override)与重载(Overload)
重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
注:子类和父类的方法名和参数一样
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
Animal a = new Animal(); //实例化
Animal d = new Dog(); //实例化,注意此处是 Animal 类实例化,Dog对象
a.eat();
d.eat();
d.eatTest(); // 此处报错,Animal 类中无eatTest()方法,不可重写
}
}
class Animal{ //父类
public void eat() { //方法
System.out.println("animal:eat");
}
}
class Dog extends Animal{ //继承
public void eat() { //方法
System.out.println("Dog:eat");
}
public void eatTest() { //方法
System.out.println("Dog");
}
}
注:当需要在子类中调用父类的被重写方法时,要使用super关键字。
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
注:均在同一个类里,方法名相同,参数不同
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
例:
package Test_hello;
public class Hello {
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));
}
}
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";
}
}
结果:
test1
1
test2
test3
returntest3
test4
returntest4
5、抽象类
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
声明抽象方法会造成以下两个结果:
如果一个类包含抽象方法,那么该类必须是抽象类。
任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。
例:
public abstract class Employee //抽象类,关键词 abstract
{
private String name;
private String address;
private int number;
public abstract double computePay(); //抽象方法
//其余代码
}
6、多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
多态性是对象多种表现形式的体现。
多态的优点:消除类型之间的耦合关系、可替换性、可扩充性、接口性、灵活性、简化性。
多态存在的三个必要条件: 继承、重写、父类引用指向子类对象。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal { //抽象类
abstract void eat(); //抽象方法
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
结果:
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠
7、封装
封装是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装的优点
1. 良好的封装能够减少耦合。
2. 类内部的结构可以自由修改。
3. 可以对成员变量进行更精确的控制。
4. 隐藏信息,实现细节。
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
EncapTest encap = new EncapTest();
encap.setName("James");
encap.setAge(20);
System.out.print("Name : " + encap.getName()+
" Age : "+ encap.getAge());
}
}
class EncapTest{
private String name; //私有成员
private int age; //私有成员
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge( int newAge){
age = newAge;
}
public void setName(String newName){
name = newName;
}
}
结果:
Name : James Age : 20
8、接口
接口,是抽象方法的集合,接口通常以interface来声明。
一个类通过继承接口的方式,从而来继承接口的抽象方法。
类描述对象的属性和方法。接口则包含类要实现的方法。
接口无法被实例化,但是可以被实现。
一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
接口与类相似点:
一个接口可以有多个方法。
接口文件保存在 .java 结尾的文件中,文件名使用接口名。
接口的字节码文件保存在 .class 结尾的文件中。
接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别:
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法。
接口不能包含成员变量,除了 static 和 final 变量。
接口不是被类继承了,而是要被类实现。
接口支持多继承。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
接口的声明:
[可见度] interface 接口名称 [extends 其他的接口名名] {
// 声明变量
// 声明方法
}
接口的实现:
class 类名implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
接口的继承:
public interface 接口2 extends 原接口
{
// 声明方法
}
接口的多继承:
在Java中,类的多继承是不合法,但接口允许多继承。
public interface 接口3 extends 接口2, 接口1
例:
package Test_hello;
public class Hello {
public static void main(String[] args) { //主函数
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
interface Animal{ //接口的声明,interface
public void eat(); // 声明方法
public void travel(); // 声明方法
}
class MammalInt implements Animal{ //接口的实现,类要实现接口中所有的方法
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
}
结果:
Mammal eats
Mammal travels
9、包(package)
把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
例:
/* 文件名: Animal.java */
package Test_hello; //包
interface Animal { //定义接口
public void eat();
public void travel();
}
接下来,在同一个包中加入该接口的实现:
/* 文件名 : Hello.java */
package Test_hello; //包
public class Hello {
public static void main(String[] args) { //主函数
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
class MammalInt implements Animal{ //接口实现
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
}