1. 封装:隐藏对象的属性和实现细节,仅对外公开接口。
(1)private(私有变量):只能被定义它的类访问。
(2)protected(受保护变量):可以被定义它的类及子孙类直接访问,也可以由同一包中的其他类直接访问。
(3)public(公共变量):可以被任何类进行访问。
(4)package:可以被定义它的类和同一个包中的其他类(包括派生子类)所访问.(包变量在声明时常常省略package关键字),在其他包中的子类则不能访问父类的包变量
运行结果为:/* public class Singleton { //静态的,保留自身的引用 private static Singleton test = new Singleton(); //必须是私有的构造函数 private Singleton(){ } //公共的静态方法 public static Singleton getInstance(){ return test; } } */ public class Singleton { //静态的,保留自身的引用 private static Singleton test = null; private int size = 512; //必须是私有的构造函数 private Singleton(){ } //公共的静态方法 public static Singleton getInstance(){ if(test == null){ test = new Singleton(); } return test; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public static void main(String[] args) { Singleton[] singleInstance = new Singleton[5]; //使用内存中的同一个实例,因此结果均为512 for(int i=0;i<5;i++){ singleInstance[i] = Singleton.getInstance();//静态方法直接可以类名.方法 System.out.println(singleInstance[i].getSize()); } singleInstance[4].setSize(1000); for(int i=0;i<5;i++){ System.out.println(singleInstance[i].getSize()); } } }
512 512 512 512 512 1000 1000 1000 1000 1000
2. 继承:
(1)复用其他对象的代码有两种方法:
①. 继承:是由子对象完全继承父对象的数据和操作,"is"的关系。
②. 包含:把一个对象作为另外一个对象的一部分,从而达到复用的目的,"has"的关系。
(2)继承的理解:
①. 继承是类实现可重用性和可扩充性的关键特征,在继承关系下类之间组成网状的层次结构。
②. 继承避免公用代码的重复开发,减少代码的冗余。
③. 通过继承增强一致性,从而减少模块间的接口和界面
(3)单继承(Java支持):子类只能有一个直接父类,多继承(Java不支持):子类可以有多个直接父类。
Java不支持类的多继承,但支持接口的多继承。继承通过关键字extends实现。
构建一个Person类:
public class Person { protected String name; protected char sex; protected int age; public Person(){ super();//表示对它的直接父类的构造函数的使用 System.out.println("父类的构造函数"); } public Person(String name, char sex, int age) { //super(); this.name = name;//this加“.”表示获取本类的使用 this.sex = sex; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //添加方法 public String getDetails(){ return "这个人是:"+this.name; } }
构造一个继承Person的Student类:public class Student extends Person{//新增添了两个变量 <span style="white-space:pre"> </span>protected int chinese,math; public Student(){ super();//调用父类无参构造函数 System.out.println("Student类构造函数"); } public Student(String name, char sex,int age,int chinese,int math){ //super(name,sex,age); super.name = name; //通过super调用父类成员变量 super.sex = sex; super.age = age; this.chinese = chinese; this.math = math; } public double average(){ return (this.chinese+this.math)/2.0; } //方法覆盖 public String getDetails(){ return "这个人是:"+this.name+",平均分是:"+this.average(); } }
(4)变量隐藏:在子类对父类的继承中,如果子类与父类的成员变量同名,此时成为子类隐藏(override)了父类的成员变量。子类若要引用父类的同名变量,要用super关键字做前缀加圆点操作符引用,即“super.变量名”。
(5)方法覆盖:
在子类中重写父类的方法,它们的名称,参数以及返回类型完全相同。通过改写方法体来完成不同的功能。注意子类方法不能缩小父类方法的访问权限 。
(6)super关键字:如果子类调用父类的构造函数,则通过super()调用来实现。
如果子类调用父类的同名方法,则通过super.方法名()来实现。
(7)this关键字:this变量代表对象本身
当类中有两个同名变量,一个属于类的成员变量,而另一个属于某个特定的方法,使用this区分成员变量和局部变量,使用this简化构造函数的调用
引用自身对象的成员变量,引用自身对象的成员方法,调用自身的构造方法--this(参数)
3. Java多态
(1)静态多态:在编译时,就可以被系统识别,也称为静态联编,重载(overload)方法采用静态联编的方法实现方法重载,在一个类中定义多个同名的方法,但这些方法的参数列表必须不一样,即参数的个数不同,或参数类型不同,或参数顺序不同,注意返回类型不能用来区分重载。
(2)动态多态:在编译时不能被系统识别,而是在 运行时才被系统识别,也称为动态联编, 覆盖(override)方法,抽象方法和接口采用动态联编的方法实现
class sup{//定义一个sup类 public int x,y; sup(int a,int b){ this.x = a; this.y = b; } public void display(){ int z = this.x+this.y; System.out.println("add="+z); } } class sub extends sup{//定义的sub类继承sup sub(int a,int b){ super(a,b);//调用父类sup的构造函数 } public void display(){//方法覆盖 int z = this.x * this.y; System.out.println("product="+z); } } //dispaly在编译时不能被系统识别,而是在运行时才能被识别到 public class ResultDemo extends sub{//ResultDemo继承sub类 ResultDemo(int x,int y){ super(x,y);//调用父类sub的构造函数 } public static void main(String[] args) { sup num1 = new sup(7, 14); sub num2 = new sub(7, 14); ResultDemo num3 = new ResultDemo(7, 14); num1.display(); num2.display(); num3.display(); //动态联编运行时会检查num1的内存是sub的实例还是sup的实例 num1 = num2; num1.display(); num1 = num3; num1.display(); } }
执行结果为:add=21 product=98 product=98 product=98 product=98
(3)父类和子类对象的转换
①. 自动转换:向上映射都是自动转换
②. 强制类型转换:父类对象转换为子类对象
格式:instanceof 判断前面的对象是否为后面的类的实例
if(父类对象名 instanceof 子类名){
子类对象名 = (子类名)父类对象名;
}else{
…
}
class ASuper{ String s = "calss:A"; } class BSub extends ASuper{//继承关系 String s = "class:B"; //变量隐藏 } public class TypeV { public static void main(String[] args) { BSub b1,b3; ASuper a1,a2,a3; BSub b2 = new BSub(); a1 = b2;//向上映射 a2 = b2;//向上映射 System.out.println(a1.s); System.out.println(a2.s); b1 = (BSub)a1;//向下映射,静态联编 System.out.println(b1.s); a3 = new ASuper(); //b3 = (BSub)a3; if(a3 instanceof BSub) b2 = (BSub)a3; else System.out.println("can not be transformed"); } }
运行结果 :calss:A calss:A class:B can not be transformed