首頁 web前端 js教程 什麼是物件導向程式設計(OOP)?物件導向程式設計的特點

什麼是物件導向程式設計(OOP)?物件導向程式設計的特點

Jun 24, 2017 pm 02:48 PM
javascript 物件 程式設計 面向

什麼是物件導向程式設計(OOP)?用物件的想法去寫程式碼,就是物件導向程式設計。

物件導向程式設計的特點

  • #抽象:抓住核心問題

  • 封裝:只能透過物件來存取方法

#繼承:從已有物件繼承出新的物件

  • 多態:多物件的不同形態

  • 物件的組成

屬性:物件下面的變數叫做物件的屬性

方法:物件下面的函數叫做物件的方法

var arr = [];
arr.number = 10;  //对象下面的变量:叫做对象的属性//alert( arr.number );//alert( arr.length );arr.test = function(){  //对象下面的函数 : 叫做对象的方法alert(123);
};

arr.test();//方法arr.push();//方法arr.sort();
登入後複製
建立一個物件

var obj=new Object();//创建一个空的对象obj.name='小明';  //属性obj.showName=function(){   //方法alert(this.name);//this指向obj }
 obj.showName();//小明
登入後複製

 

    #如果需要建立兩個或多個物件
  • var obj1=new Object();//创建一个空的对象obj1.name='小明';  //属性obj1.showName=function(){   //方法alert(this.name);//this指向obj }
     obj1.showName();//小明var obj2=new Object();//创建一个空的对象obj2.name='小灰';  //属性obj2.showName=function(){   //方法alert(this.name);//this指向obj }
     obj2.showName();//小灰
    登入後複製

  • #使用Object函數或物件字面量都可以建立面向對象,但需要建立多個物件時,會產生
  • 大量的重複程式碼

    ,可透過工廠方式來解決這個問題

  • 工廠方式   ------------ --------  
  • 物件導向中的封裝函數

    //工厂方式 : 封装函数function createPerson(name){var obj = new Object();
        obj.name = name;
        obj.showName = function(){
            alert( this.name );
        };return obj;    
    }var p1 = createPerson('小明');
    p1.showName();var p2 = createPerson('小强');
    p2.showName();
    登入後複製

建立物件用工廠方式來實現,可以傳遞參數,由於創建物件都是使用Object的原生建構子來實現的,因此無法辨識物件類型

建構子模式  -------- ------------   給一個物件添加方法

//new 后面调用的函数叫构造函数function CreatePerson(name){this.name=name;this.showName=function(){
                alert(this.name);
            }
        }var p1=new CreatePerson('小明');//当new去调用一个函数时,函数中的this就是创建出来的对象而函数中的返回值就是this        p1.showName();var p2=new CreatePerson('小强');
        p2.showName();
登入後複製

使用自訂的建構函數,定義物件類型的屬性和方法,與工廠方式的差異:

#沒有明確的建立物件

直接將屬性與方法賦給this物件

####沒有return語句############### ###上面範例中:CreatePerson建構函式產生的兩個物件p1與p2都是CreatePerson的實例############雖然建構子解決了上面工廠方式的問題,但它一樣存在缺點,就是在創建物件時,每個物件都有一套自己的方法,###每定義一個函數都實例化了一個物件###############例如:## #######
function CreatePerson(name){    this.name = name;this.showName = function(){
        alert( this.name );
    };
    
}var p1 = new CreatePerson('小明');//p1.showName();var p2 = new CreatePerson('小强');//p2.showName();alert( p1.showName == p2.showName );  //false  它们的值相同,地址不同
登入後複製
#########測試範例中的p1.showName與p2.showName是否會相等,彈出的結果是false,表示p1和p2實例都包含一個不同的showName實例############再來舉幾個例子:#########
var a = [1,2,3];var b = [1,2,3];

alert( a == b );  //false  值相同,地址不同var a = 5;var b = a;b += 3
alert(b); //8alert(a); //5   基本类型 : 赋值的时候只是值的复制
登入後複製
###### ######
var a = [1,2,3];var b = a;b.push(4);
alert(b);  //[1,2,3,4]alert(a);  //[1,2,3,4]   对象类型 : 赋值不仅是值的复制,而且也是引用的传递
登入後複製
######
var a = [1,2,3];var b = a;
b = [1,2,3,4];
alert(b); //[1,2,3,4]alert(a); //[1,2,3]
登入後複製
## #

对比上面的几个例子,不难看出基本类型和对象类型的区别了,对象类型的赋值不仅是值的复制,也是引用的传递;提到了对象的引用应该很清楚上述p1.showName==p2.showName为何会返回结果是false

原型模式(prototype)  --------------------   给一类对象添加方法

原型(prototype):重写对象下面公用的属性或方法,让公用的属性或方法在内存中只存在一份(提高性能),也就是说所有在原型对象中创建的属性或方法都直接被所有对象实例共享。

  • 原型:类比css中的class

  • 普通方法:类比css中的style

var arr = [1,2,3,4,5];var arr2 = [2,2,2,2,2];

Array.prototype.sum = function(){//原型prototype : 要写在构造函数的下面var result = 0;for(var i=0;i<this.length;i++){
        result += this[i];
    }return result;
};

alert( arr.sum() );  //15alert( arr2.sum() );  //10
登入後複製

原型优先级:如果在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,该属性将会屏蔽原型中的那个属性

例子1:

var arr = [];
arr.number = 10;
Array.prototype.number = 20;

alert(arr.number);//10
登入後複製

例子2:

Array.prototype.a=12;//原型属性var arr=[1,2,3];
alert(arr.a);//12arr.a=5;//实例属性alert(arr.a);//5
登入後複製

工厂方式之原型

function CreatePerson(name){//普通方法this.name=name;
}
CreatePerson.prototype.showName=function(){//原型alert(this.name);
}var p1=new CreatePerson(&#39;小明&#39;);
p1.showName();var p2=new CreatePerson(&#39;小强&#39;);
p2.showName();
alert( p1.showName== p2.showName);//true
登入後複製

由上述例子中:p1.showName== p2.showName弹出的结果是true,可见原型解决了构造函数中“每定义一个函数都实例化了一个对象”的问题

原型的运用

选项卡实例:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>选项卡</title><style>#div1 div{width:400px;height:300px;border:1px solid #ccc;overflow: hidden;display: none;margin: 15px 0;}#div1 input{color: #fff;width:100px;height:40px;background: darkseagreen;border:none;font-size: 14px;letter-spacing: 5px;}#div1 p{font-size: 20px;line-height: 24px;text-align: center;color:darkgreen;}#div1 .title{padding: 0;font-weight: bold;}#div1 .active{background:sandybrown;color:#fff;}</style><script>window.onload=function(){var oDiv=document.getElementById('div1');var aInput=oDiv.getElementsByTagName('input');var aDiv=oDiv.getElementsByTagName('div');var i=0;for(i=0;i<aInput.length;i++){
                aInput[i].index=i;
                aInput[i].onmousemove=function(){for(var i=0;i<aInput.length;i++){
                        aInput[i].className=&#39;&#39;;
                        aDiv[i].style.display=&#39;none&#39;;
                    }
                    aInput[this.index].className=&#39;active&#39;;
                    aDiv[this.index].style.display=&#39;block&#39;;
                }
            }
        }</script></head><body><div id="div1"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div></body></html>
登入後複製

效果(鼠标经过按钮时选项卡切换):


 

面向对象选项卡:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>选项卡</title><style>#div1 div,#div2 div{width:400px;height:300px;border:1px solid #ccc;overflow: hidden;display: none;margin: 15px 0;}#div1 input,#div2 input{color: #fff;width:100px;height:40px;background: darkseagreen;border:none;font-size: 14px;letter-spacing: 5px;}#div1 p,#div2 p{font-size: 20px;line-height: 24px;text-align: center;color:darkgreen;}#div1 .title,#div2 .title{padding: 0;font-weight: bold;}#div1 .active,#div2 .active{background:sandybrown;color:#fff;}</style><script>window.onload=function(){var t1=new TabSwitch('div1');
            t1.switch();           var t2=new TabSwitch('div2');//面向对象的复用性            t2.switch();
            t2.autoPlay();/*alert(t2.switch==t1.switch);//ture*/}function TabSwitch(id){this.oDiv=document.getElementById(id);this.aInput=this.oDiv.getElementsByTagName('input');this.aDiv=this.oDiv.getElementsByTagName('div');this.iNow=0;//自定义属性}
        TabSwitch.prototype.switch=function(){//原型for(var i=0;i<this.aInput.length;i++){var This=this;//将指向面向对象的this保存下来this.aInput[i].index=i;this.aInput[i].onmousemove=function(){
                    This.tab(this);//This指向面向对象           this指向this.aInput[i]                }
            }
        }
        TabSwitch.prototype.tab=function(obj){//原型for(var i=0;i<this.aInput.length;i++){this.aInput[i].className=&#39;&#39;;this.aDiv[i].style.display=&#39;none&#39;;
            }this.aInput[obj.index].className=&#39;active&#39;;this.aDiv[obj.index].style.display=&#39;block&#39;;
        }//自动播放        TabSwitch.prototype.autoPlay=function(){var This=this;
            setInterval(function(){if(This.iNow==This.aInput.length-1){
                    This.iNow=0;
                }else{
                    This.iNow++;
                }for(var i=0;i<This.aInput.length;i++){
                    This.aInput[i].className=&#39;&#39;;
                    This.aDiv[i].style.display=&#39;none&#39;;
                }
                This.aInput[This.iNow].className=&#39;active&#39;;
                This.aDiv[This.iNow].style.display=&#39;block&#39;;
            },1000);
        }</script></head><body><div id="div1"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div><div id="div2"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div></body></html>
登入後複製

效果(第二个选项卡加了一个自动切换功能):


 

面向对象中this的问题

一般会出现问题的情况有两种:

  • 定时器

  • 事件

例子1:

//定时器function Aaa(){          var _this=this;//将当前this值保存this.a=12;
          setInterval(function(){//定时器中this指向window                _this.show();
           },1000);
}
Aaa.prototype.show=function(){
           alert(this.a);
 }var obj=new Aaa();//12
登入後複製

例子2:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>面向对象中this的问题-----事件</title><script>function Bbb(){var _this=this;this.b=5;
            document.getElementById('btn1').onclick=function(){//点击事件                _this.show();
            }}
登入後複製
        Bbb.prototype.show=function(){ alert(this.b); } window.onload=function(){var p2=new Bbb();
        }</script></head><body><input id="btn1" type="button" value="按钮"></body></html>
登入後複製

上面两个是分别对定时器和事件中this问题的解决方法,即将指向对象的this保存到了_this中,在嵌套函数中调用对象的方法或属性时用  _this.属性 或  _this.方法

再来个实例:

拖拽效果:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>最初写的拖拽效果</title>
   <style>   #div1{   width:100px;   height:100px;   background: red;   position: absolute;   }
   </style><script>window.onload=function(){var oDiv=document.getElementById('div1');
            oDiv.onmousedown=function(ev){var oEvent=ev||event;var disX=0;var disY=0;var disX=oEvent.clientX-oDiv.offsetLeft;var disY=oEvent.clientY-oDiv.offsetTop;
                document.onmousemove=function(ev){var oEvent=ev||event;
                    oDiv.style.left=oEvent.clientX-disX+'px';
                    oDiv.style.top=oEvent.clientY-disY+'px';
                };
                document.onmouseup=function(){
                    document.onmousemove=null;
                    document.onmouseup=null;
                };return false;
            }
        }</script></head><body><div id="div1"></div></body></html>
登入後複製

面向对象的拖拽

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>面向对象写的拖拽效果</title><style>#div1{width:100px;height:100px;background: red;position: absolute;}</style><script>window.onload=function(){var p=new Darg('div1');
            p.init();

        }function Darg(id){this.oDiv=document.getElementById(id); //属性this.disX=0;//属性this.disY=0;//属性}
        Darg.prototype.init=function(){//原型  方法var This=this;this.oDiv.onmousedown=function(ev){var oEvent=ev||event;
                This.fnDown(oEvent);return false;
            }
        }
        Darg.prototype.fnDown=function(ev){//原型   方法var This=this;this.disX=ev.clientX-this.oDiv.offsetLeft;this.disY=ev.clientY-this.oDiv.offsetTop;
            document.onmousemove=function(ev){var oEvent=ev||event;
                This.fnMove(oEvent);
            };
            document.onmouseup=function(){
                This.fnUp();
            };
        }
        Darg.prototype.fnMove=function(ev){//原型this.oDiv.style.left=ev.clientX-this.disX+'px';this.oDiv.style.top=ev.clientY-this.disY+'px';
        }
        Darg.prototype.fnUp=function(){//原型            document.onmousemove=null;
            document.onmouseup=null;
        }</script></head><body><div id="div1"></div></body></html>
登入後複製

 

以上是什麼是物件導向程式設計(OOP)?物件導向程式設計的特點的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用正規表示式去除 PHP 數組中的重複值 使用正規表示式去除 PHP 數組中的重複值 Apr 26, 2024 pm 04:33 PM

使用正規表示式從PHP數組中移除重複值的方法:使用正規表示式/(.*)(.+)/i匹配並取代重複項。遍歷數組元素,使用preg_match檢查匹配情況。如果匹配,請跳過值;否則,將其添加到無重複值的新數組中。

如何將 MySQL 查詢結果陣列轉換為物件? 如何將 MySQL 查詢結果陣列轉換為物件? Apr 29, 2024 pm 01:09 PM

將MySQL查詢結果陣列轉換為物件的方法如下:建立一個空物件陣列。循環結果數組並為每一行建立一個新的物件。使用foreach迴圈將每一行的鍵值對賦給新物件的對應屬性。將新物件加入到物件數組中。關閉資料庫連線。

PHP 函數如何傳回物件? PHP 函數如何傳回物件? Apr 10, 2024 pm 03:18 PM

PHP函數可以透過使用return語句後接物件實例來傳回對象,從而將資料封裝到自訂結構中。語法:functionget_object():object{}。這允許創建具有自訂屬性和方法的對象,並以對象的形式處理資料。

C++ 函式回傳物件時有什麼需要注意的? C++ 函式回傳物件時有什麼需要注意的? Apr 19, 2024 pm 12:15 PM

在C++中,函數傳回物件需要注意三點:物件的生命週期由呼叫者負責管理,以防止記憶體洩漏。避免懸垂指針,透過動態分配記憶體或返回物件本身來確保物件在函數返回後仍然有效。編譯器可能會最佳化傳回物件的副本生成,以提高效能,但如果物件是值語義傳遞的,則無需副本生成。

數組和物件在 PHP 中的差異是什麼? 數組和物件在 PHP 中的差異是什麼? Apr 29, 2024 pm 02:39 PM

PHP中,數組是有序序列,以索引存取元素;物件是具有屬性和方法的實體,透過new關鍵字建立。數組存取透過索引,物件存取通過屬性/方法。數組值傳遞,物件參考傳遞。

程式設計是乾啥的,學了有什麼用 程式設計是乾啥的,學了有什麼用 Apr 28, 2024 pm 01:34 PM

1、程式設計可用於開發各種軟體和應用程序,包括網站、手機應用程式、遊戲和數據分析工具等。它的應用領域非常廣泛,幾乎涵蓋了所有行業,包括科學研究、醫療保健、金融、教育、娛樂等。 2.學習程式設計可以幫助我們提升問題解決能力和邏輯思考能力。在程式設計過程中,我們需要分析和理解問題,找出解決方案,並將其轉換為程式碼。這種思維方式能夠培養我們的分析和抽象能力,提升我們解決實際問題的能力。

使用 Python 解決問題:作為初學者,解鎖強大的解決方案 使用 Python 解決問題:作為初學者,解鎖強大的解決方案 Oct 11, 2024 pm 08:58 PM

Python 讓初學者能夠解決問題。

C++ 程式設計謎題片段:激發思維,提升程式設計水平 C++ 程式設計謎題片段:激發思維,提升程式設計水平 Jun 01, 2024 pm 10:26 PM

C++程式設計謎題涵蓋斐波那契數列、階乘、漢明距離、陣列最大值和最小值等演算法和資料結構概念,透過解決這些謎題,可以鞏固C++知識,提升演算法理解和程式設計技巧。

See all articles