1 封裝
1.1 封裝性的概念
1、封裝性是面向對象思想的三大特性之一
2、是指隱藏對象的屬性和實現細節,僅對外提供公共的訪問方式
3、封裝有:
屬性的封裝
方法的封裝(方法本來就是一種封裝體)
類的封裝(屬性和方法的集體封裝)
組件的封裝
模塊化封裝
系統級封裝
4、封裝原則:
將不需要對外提供的內容都隱藏起來
把屬性都隱藏,提供公共方法對其訪問
5、函數也是封裝的一種體現,函數是java中最小的封裝 體
1.2 封裝的好處
1、模塊化,便於使用
2、信息隱藏,將變化隔離
3、代碼重用
4、插件化易於調試
5、提高安全性
1.3 屬性的封裝
1、把屬性定義爲私有的(只能在本類中直接訪問)
2、爲屬性提供get/set方法(通過這兩個方法間接訪問類中的屬性)
將屬性使用private封裝後,類以外即使建立了對象也不能直接訪問了 。但是人應該有年齡,就需要在person類中提供對應訪問age的方式(set()和get())
就可以在訪問方式中加入邏輯判斷等語句 對訪問的數據進行操作,提高代碼的健壯性
public class Object_Encapsulation {
public static void main(String[] args) {
Person p=new Person();
p.setAge(20);
//p.speak();
}
}
class Person{
private int age;
//對外提供訪問方式
public void setAge(int age){
if (age>0 && age<130){
this.age=age;
speak();
}
else
System.out.println("age feifa");
}
public int getAge(){
return age;
}
//一個成員變量的訪問方式一般會對應兩種方式一個是set (沒有返回值)一個時get(返回值時int)
void speak(){
System.out.println("age="+age);
}
}
public class SixtyEight_SixtyNine_Seventy {
public static void main(String[] args) {
Person p = new Person();
p.name = "baobao";
p.age = 20;
p.say();
//----------------------------------
Personn p1 = new Personn();
p1.setName("包包");
p1.setAge(22);
p1.say();
}
}
class Person{
String name;//如果沒有將類的屬性進行封裝,外部類可以隨意修改類的屬性
int age;
void say(){
System.out.println("我是:"+name+",今年"+age+"歲");
}
}
class Personn{
private String name;//將類的屬性進行封裝,外部類不可以隨意修改類的屬性
private int age;
void say(){
System.out.println("我是:"+getName()+",今年"+getAge()+"歲");
}
//將類的屬性進行封裝後,需要提供一個設置屬性值和獲取屬性值得方法(對外提供接口) 對應的是set 和 get
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
2 繼承
2.1 繼承的基本概念:
1、繼承是面向對象的三大特性之一
2、被繼承的類稱爲父類(超類),繼承父類的類稱爲子類(派生類)
3、繼承是指一個對象直接使用另一個對象的屬性和方法(繼承之後才能使用)
4、通過繼承可以實現代碼重用
2.2 使用繼承的要求
1、將每個類的共性提取出來單獨放在一個類中來描述
2、然後讓這個類與其他每個類之間有點關係這樣就可以了
3、注意:千萬不要爲了獲取其他類的功能,簡化代碼而繼承
4、必須是類與類之間有所屬關係纔可以繼承
5、例如:將學生和工人的共性(共同屬性,共同方法)描述提取出來。單獨進行描述。只要讓學生和工人與單獨描述的這個類有關係,就可以了。
2.3 繼承的好處
1、提高了代碼的複用性
2、讓類與類之間產生了關係,有了這個關係,纔有了多態的特性
2.4 繼承的語法
public class extendsDemo {
public static void main(String[] args) {
HomeChicken c1 = new HomeChicken();
c1.desc();
}
}
//父類
class Chicken{
String name;
public Chicken(){}
public Chicken(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void desc(){
System.out.println("我是一隻戰鬥雞");
}
}
//子類
class HomeChicken extends Chicken{
}
//子類
class Pheasant extends Chicken{
}
2.5 代碼實例
public class ExtendsDemo1 {
public static void main(String[] args) {
}
}
class Person{
String name;
int age;
}
class Student extends Person{
void study(){
System.out.println("good study");
}
}
class Worker extends Person{
void work(){
System.out.println("good work");
}
}
2.6 繼承中使用時需要注意的
1、java不支持多繼承:java語言中只支持單繼承不支持多繼承(一個類繼承了另一個類就不能在繼承其他類了)
因爲多繼承容易帶來安全隱患 當多個父類中定義了相同功能,但功能內容不同時,子類對象不確定要運行哪一個。
但是java保留了這種機制,並用另一種體現形式來完成表現叫做多實現
2、java支持多層繼承:java語言中支持多層繼承 ,就是一個繼承體系
3、繼承只能繼承非私有的屬性和方法
4、如何使用一個繼承體系中的功能:想要使用體系,先查閱體系父類的描述,因爲父類中定義的是該體系中的共性功能通過了解共性功能,就可以知道該體系的基本功能
5、那麼具體調用時,要創建最子類的對象, 爲什麼呢?
(1)是因爲有可能父類不能創建對象(抽象類)
(2)是創建子類對象可以使用更多的功能,包括基本的也包括特有的
簡單一句話就是:查閱父類功能,創建子類對象使用功能
6、構造方法不能被繼承
7、那麼在繼承中不能繼承父類的私有成員,怎麼辦呢
(1)訪問修飾符:public(公有) private(私有) default(默認(本包中的所有類都可以訪問)) protected(保護型(專門繼承用的,子類的對象都能狗使用被該修飾符修飾的屬性或者方法))
(2)非私有:public(公有) default(默認) protected(保護型)
public class oneHundredAndNineteenFive {
public static void main(String[] args) {
HomeDog d1 = new HomeDog("小白");
d1.name = "小黑";
d1.desc();
/*下面這個類不是Dog的子類,所以創建了對象也不能夠使用Dog裏的共性屬性和方法
fuck f = new fuck();
f.name = "西安";
f.desc();
*/
}
}
//父類
class Dog{
protected String name;//對於父類的共性屬性可以使用該修飾符,這樣子類是可以繼承到的
public Dog(){}
public Dog(String name) {
super();
this.name = name;
}
protected void desc(){
System.out.println("我是一隻戰鬥雞"+name);
}
}
//子類
class HomeDog extends Dog{
public HomeDog(String name) {
this.name = name;
}
}
//子類
class PheasantDog extends Dog{
}
class fuck{
}
3 多態
3.1 多態性的概念
1、多態性是面向對象的三大特性之一
2、可以理解爲事物存在多種體現形態。比如動物:貓,狗
3.2 多態性的兩種情況
1、方法的重載和重寫
2、對象的多態性
3.3 對象的多態性
1、多態的體現
父類的引用指向了自己的子類對象
父類的引用也可以接收自己的子類對象
2、多態的前提
必須是類與類之間有關係,要麼繼承,要麼實現。
通常還有一個前提就是存在覆蓋
3.4 多態的好處和弊端
多態的好處:
多態的出現大大地提高了擴展性,前期的代碼可以使用後期的代碼
多態的弊端:
提高了擴展性,但是隻能使用父類的引用訪問zi類中的共性成員(不能訪問子類的特有的成員)
abstract class Animal{
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("喫魚");
}
public void CatchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("喫骨頭");
}
public void kanjia(){
System.out.println("看家");
}
}
class Pig extends Animal{
public void eat(){
System.out.println("飼料");
}
public void gongDi(){
System.out.println("拱地");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
Animal a = new Cat();//類型提升,向上轉型
//function(new Cat());
//如果想要調用貓的特有方法時,如何操作
//強制將父類的引用,轉成子類類型,向下轉型
//Cat c = new Cat();//錯誤 又new了一隻新貓
//Cat c = (Cat)a;//強制將父類的引用轉成子類類型,強制類型轉換,將動物類型轉換成貓
//c.catchMouse();
/*
Animal a = new Animal();
Cat c = (Cat)a;
不能將父類對象轉換成子類 類型,自始自終都是類型在變化
能轉換的是父類的引用指向了子類對象是,
*/
}
public static void function(Animal c){//相當於Animal c = new Cat();父類的引用也可以接收自己的子類對象
c.eat();
//instanceof用於判斷對象的具體類型
if (c instanceof Cat){
Cat a = (Cat)c;
a.catchMouse();
}
else if (c instanceof Dog){
Dog a = (Dog)c;
c.kanjia();
}
//通常情況下我們不會這麼判斷,因爲擴展性很差。如果加個子類就要再判斷一次.有兩種情況是用這種方法來判斷的:子類是有限的,比如人要麼男人要麼女人
}
}
3.5 在多態中成員變量的特點:
在編譯時期,參閱引用型變量所屬的類中是否有調用的成員變量,如果有編譯通過,如果沒有編譯失敗
在運行時期,參閱引用型變量所屬的類中是否有調用的成員變量,並運行該所屬類中的成員變量
簡單總結就是:無論編譯和運行,都參考左邊
class Fu{
int num = 3;//如果父類沒有該num,會編譯失敗。
}
class Zi extends Fu{
int num = 4;
}
class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.num);//結果是3
}
}
3.6 在多態中成員函數(非靜態)的特點:
在編譯時期,參閱引用型變量所屬的類中是否有調用的方法,如果有編譯通過,如果沒有編譯失敗
在運行時期,參閱對像所屬的類中是否有調用的方法
簡單總結就是:成員函數在多態調用時,編譯看左邊,運行看右邊
class Fu{
void show(){
System.out.pritnln("Fu show");
}
}
class Zi extends Fu{
void show(){
System.out.pritnln("Zi show");
}
}
class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
f.show();//結果是Zi show
}
}
3.7 在多態中,靜態成員函數的特點:
在編譯時期,參閱引用型變量所屬的類中是否有調用的靜態方法,如果有編譯通過,如果沒有編譯失敗
在運行時期,參閱引用型變量所屬的類中是否有調用的靜態方法
簡單總結就是:無論編譯和運行都參考左邊
class Fu{
static void show(){
System.out.pritnln("Fu show");
}
}
class Zi extends Fu{
static void show(){
System.out.pritnln("Zi show");
}
}
class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
f.show();//結果是Fu show
}
}