java的封装,继承,多态
1 封装
1.1 封装
指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。
优点:(1).良好的封装能够减少耦合;(2)类内部的结构可以自由修改;(3)可以对成员变量进行更精确的控制;(4) 隐藏信息,实现细节。
实现封装步骤:(1)将属性私有化用private修饰;(2)每个属性提供对外的公共访问方法。
1.2 javaBean类
标准的javaBean类需要满足以下两点:(1)该类是公共的(public) ;(2)私有化属性并且提供getter/setter方法。
2 继承
2.1 相关概念
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
目的:实现代码的复用。
语法:class subClass extends superClass {}
特点:(1)子类继承父类中的所有成员(在权限范围内,如被private修饰的属性不能通过子类访问,要通过父类的非private属性方法去访问);
(2)子类不能继承父类的构造器,只能用super调用;
(3)子类的继承关系是单继承,子类只能有一个直接父类,但父类可以有多个子类;
(4)继承具有传递性,如果没有直接继承父类,会默认继承java.lang.Object类;
(5)extends关键字为扩展的意思,子类不是父类的子集是父类的扩展。
示例代码如下:
public class Test {public static void main(String[] args) {Dog d = new Dog("黄色",4);d.lookHome();Cat c = new Cat("小花",4);c.catchMouse();}
}
class Animal {private String furColor;private int legNumber;public Animal() {}public Animal(String furColor, int legNumber) {this.furColor = furColor;this.legNumber = legNumber;}public String getFurColor() {return furColor;}public void setFurColor(String furColor) {this.furColor = furColor;}public int getLegNumber() {return legNumber;}public void setLegNumber(int legNumber) {this.legNumber = legNumber;}public void eat() {System.out.println("吃饭");}
}
class Cat extends Animal {public Cat() {super();}public Cat(String furColor, int legNumber) {super(furColor, legNumber);}public void catchMouse() {System.out.println("抓老鼠");}}
class Dog extends Animal {public Dog() {super();}public Dog(String furColor, int legNumber) {super(furColor, legNumber);}public void lookHome() {System.out.println("看家");}}
2.2 给属性赋值的先后顺序
①通过创建对象给属性赋初始值->②显示给属性赋初始值->③通过构造器给属性赋初始值->④通过setter·方法赋值
2.3 方法的重写
定义:对父类方法的重写(覆盖)。
特点:(1)一定要有继承关系;
(2)子类方法和父类方法的方法名,参数必须一致,返回值类型也可是是父类返回值类型的子类;
(3)子类方法的权限修饰符不能小于父类方法的权限修饰符;
(4)子类方法的抛出的异常不能大于父类方法抛出的异常;
(5)子类方法和父类方法同为static或非static。
2.4 方法的重载
作用:让类以统一的方式处理不同类型数据的一种手段。
特点:必须在同一个类中,方法名必须相同,参数列表必须不同(参数类型,参数长度,参数顺序),与返回值无关。
2.5 this关键字
this作用:代表当前对象或者正在创建的对象。
this修饰属性(this.属性),this修饰方法·(this.方法()),this修饰构造器(this(参数))。
注意:this修饰构造器必须放在构造器的第一行,有N个构造方法最多只能出现N-1次
public class Play {public static void main(String[] args) {Boy boy = new Boy("小明",22); Girl girl =new Girl("小红"); boy.play(girl); System.out.println("====================");girl.play(boy);}
}
//
class Boy{private String name;private int age;//无参 public Boy() {super();}public Boy(String name, int age) {this.name = name;this.age = age;}//男孩public void play(Girl g) {System.out.println(this);System.out.println("我要玩耍:"+g.getName());g.marry(this); //boy对象 小明 22}
}
class Girl{private String name;public Girl() {super();}public Girl(String name) {super();this.name = name;}public void play(Boy b) {System.out.println("我要玩耍:"+b.getName());}}
2.6 super关键字
super作用:调用父类
super修饰属性(super.属性),super修饰方法·(super.方法()),super修饰构造器(super(参数))。
super调用构造器特点:(1)默认子类构造器会隐式调用父类无参构造器;
(2)super()只能出现在构造器的首行;
(3)super()和this()不能同时出现
(4)super(参数)表示显示调用父类的相应参数的构造器
public class Test {public static void main(String[] args) {Student s=new Student();s.value();}
}
class Preson {String name;void value() {name = "人类";}
}class Student extends Country {String name;void value() {name = "学生";super.value(); //调用父类的方法System.out.println(name);System.out.println(super.name);}}
2.7 this与super的区别
this | super | |
属性 | this.属性;可以访问本类中的属性,父类中的属性 | super.属性;只能访问父类中的属性 |
行为 | this.方法();可以访问本类中的方法,父类中的方法 | super.方法();只能访问父类中的方法 |
构造器 | this(参数)表示调用当类中的其它构造器,this(参数)最多N-1个 | super(参数),表示调用父类中的构造器,构造器中默认是super() |
3 多态
多态的理解:一个事物的多种表现形态;同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,
多态必要的三个条件:继承,重写,父类引用指向子类对象。
两种实现方式:
(1)向上转型:父类 对象名 = new 子类(); //父类引用指向子类对象,自动转换
(2)向下转型:父类类型对象 instanceOf 子类类型 //相当于 子类类型 对象=(子类类型)父类类型的对象 ;
注意:(1)对于多态编译状态(看左边类型),运行状态(看右边的类型)。
(2)类的属性没有多态性(属性不能被子类的属性覆盖)
public class TestFauther {public static void main(String[] args) {//父类 对象 =new 子类();
// TestFauther t = new TestFauther();
// t.fun(new Son()); //匿名对象
// t.fun(new Daughter()); //匿名// Father f = new Son();
// f.eat();}//父类类型作为方法参数public void fun(Father f) {f.eat(); //子类重写的方法 if(f instanceof Son) {Son s=(Son)f;s.walk();}if(f instanceof Daughter) {Daughter d = (Daughter)f;d.shoping();}}
}
//父亲类
class Father{private String name;private int age;public Father() {super();}public Father(String name, int age) {super(); //Objectthis.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//public void eat() {System.out.println("父亲爱吃青菜");}}
//儿子类
class Son extends Father{private String hobby;public Son() {super();}public Son(String name, int age,String hobby) {super(name,age);this.hobby = hobby;}public String getHobby() {return hobby;}public void setSHobby(String hobby) {this.hobby = hobby;}//重写public void eat() {System.out.println("儿子爱吃肉");}public void walk() {System.out.println("儿子大步走");}}
//女儿
class Daughter extends Father{private String beauty;public Daughter() {super();}public Daughter(String name, int age,String beauty) {super(name,age);this.beauty=beauty;}public String getBeauty() {return beauty;}public void setBeauty(String beauty) {this.beauty = beauty;} //重写public void eat() {System.out.println("女儿爱吃零食");}public void shoping() {System.out.println("购物 ");}
}
4 Object类
Object是所有类的基类。
Object类的方法如下:
(1)registerNatives()方法:是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。函数的执行是在静态代码块中执行的,在类首次进行加载的时候执行。
(2)getClass()方法:也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class<?>。效果Object.class相同。 类本身也都是属于Class类的对象。为与经常意义上的对象相区分,在此称之为”类对象”
(3)hashCode()方法:是一个本地native方法,返回的是对象引用中存储的对象的内存地址
(4)equals(Object obj)方法:比较两个对象是否相同,Object中的equals比较的是对象的内存地址(对象堆地址(引用存储的))。
(5)clone() 方法:创建并且返回一个对象的拷贝之后的结果,这实现了浅拷贝。关于浅拷贝和深拷贝:浅拷贝是指当拷贝对象内部中有引用类型的属性变量,在拷贝时候,只拷贝一份引用,拷贝的引用和原引用都指向原来的对象地址。
(6)toString()方法:返回类的名称(全限定名称)加上@,然后 加上此类的哈希码的16进制
(7)wait方法: wait方法会引起当前线程阻塞,直到另外一个线程在对应的对象上调用notify或者notifyAll()方法,或者达到了方法参数中指定的时间
(8)notify()方法:通知可能等待该对象的对象锁的其他线程。由JVM(与优先级无关)随机挑选一个处于wait状态的线程。在调用notify()之前,线程必须获得该对象的对象级别锁执,行完notify()方法后,不会马上释放锁,要直到退出synchronized代码块,当前线程才会释放锁。notify()一次只随机通知一个线程进行唤醒
(9)和notify()差不多,只不过是使所有正在等待池中等待同一共享资源的全部线程从等待状态退出,进入可运行状态,让它们竞争对象的锁,只有获得锁的线程才能进入就绪状态 。
(10)finalize()方法:子类可重写此方法,以实现非内存资源的清理。此方法在GC回收给对象之前,会自动调用此方法。如果用户显示地调用此方法,代表普通方法调用,与对象的回收销毁无关。
5 访问权限修饰符
public:本包和不同包的资源都可以访问;
protected:本包和不同包下的子类可以访问;
默认的:只能在本包中进行访问;
private:只能在本类中访问
6 修饰符总结
访问权限修饰符 | 修饰符 | |
类 | ①公共类修饰符public ②默认修饰符 | ①abstract :用 abstract 修饰符修饰的类,被称为抽象类,可以被指示一个类只能作为其它类的基类 ②final :当一个类不能被继承时可用修饰符 final修饰为最终类。不能再申明子类 ③ststic:修饰类时表示该类是静态类,不能够实例化该类的对象,该类的成员为静态 |
属性 | ①public ②protected ③默认的 ④private | ①static:指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。 ②final:最终修饰符,指定此变量的值不能变 ③transient:指定该变量是系统保留,暂无特别作用的临时性变量。修饰的属性不能序列化 ④volatile:指定该变量可以同时被几个线程控制和修改 |
方法 | ①public ②protected ③默认的 ④private | ①static:指定不需要实例化就可以激活的一个方法,子类不能重写父类中的方法 ②final:指定该方法不能被重载。 ③abstract:指定此方法不需要实现,实现留给子类覆盖,必须被子类方法重写。 ④native:本地修饰符,没有方法体,调C或C++的实现 。 ⑤synchronized:同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。 |
7 ==和equals
==:用于基本类型是值比较,用于引用类型是地址比较。
equals:没有对equals方法进行重写,默认Object类中的方法,比较地址。如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
//基本类型
int i1 = 100;float f1 = 100.0f;System.out.println(i1==f1); //truechar c1 = 100;System.out.println(i1==c1); //true char c2 = 'A'; //65System.out.println(c2==65); //true
//引用类型
Object o1 = new Object();Object o2 = new Object();Object o3 = o2; System.out.println(Integer.toHexString(o1.hashCode()));System.out.println(o2.hashCode());System.out.println(o1==o2); //false System.out.println();System.out.println(o3==o2); //true
8 包装器类
所有的基本类型都有一个与之对应的类,这些类称为包装器类。对象包装器类是不可改变的,即一旦构造类包装器类,就不允许更改包装在其中的值。同时,对象包装器类还是final
,因此不能定义它们的子类。
好处:(1)类里有相应方法方便用户调用;(2)可以用类的对象和null进行比较,避免java.lang.nullPointException
8个包装器类如下
基本数据类型 | 包装器类 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
包装器类与基本数据类型,String之间的装换如下图