黑马程序员技术交流社区

标题: swift实作app 交流分項四(物件導向 OOP) [打印本页]

作者: Kuhoku    时间: 2015-6-22 04:18
标题: swift实作app 交流分項四(物件導向 OOP)
一行代码一场梦,大家好我是阿达。
       
        今天来到的小伙伴如果是从第一篇开始追到现在的话,阿达先跟你说谢谢,我想你已经前进了一大步了,到现在我们已经分享了Storyboard 的导览控制器以及表格视图控制器来建立 iphone App了。
       
        本来想要继续接下去分享关于细节修改,也就是如何让APP变得更加美观,但是我觉得应该对于之前的程式码做一些消化吸收,所以阿达今天并不打算继续分享新的功能,今天要跟大家分享的是物件导向(OOP)也就是Object Oriented Programming 的观念。

        在交流版中看到很多小伙伴们对于OOP也有疑问,所以在这边跟大家分享一下并且拿实际案例来做说明。主要经过前面几篇的引导,就算是没基础的小伙伴,也可以照着上面的图文来做出一个IPhone App ,所以接下来的部分,阿达认为小伙伴们已经下定决心要学好iOS程式并且想要提升自己的程式设计技术到更进阶的阶段了。

        没问题,我们开始吧。

        跟OC一样  Swift 是一种OOP语言。OOP也就是一种由物件(Object)所组成的,建构软体应用的方式。换句话说,大部份你的App中已经写过的程式码,都是以某些方式来处理某种物件。之前我们用过一些 UIViewController,UIImage,UITableViewController ,UINavigationController….这些都是由iOS SDK所提供的物件。

        其实像是之前的范例中,我们就建立了一些物件,像是DetailViewCOntroller 与 CustomTableCell。这些都是我们自己所建立的物件,但是小伙伴们会想说『为什么我们要用OOP』呢? 一个非常重要的理由就是,我们需要把一个复杂的软体分解成简单的多个小部分,以便更容易的开发以及维护,这里所说的小部分也就是所谓的物件。


        在这边说明一下 类别(Class),物件(Object)及实体(instance)这三者之间的关系。

        一个类别(Class)是建立物件(Object)的蓝图,一个类别是由属性跟方法来组成的,比方说黑马今天要开的课程有 iOS, Android, Java….。在这里 iOS就是黑马的物件,当然有些时候我们会在文件上面看到会叫他们『实体』,『实体』也就是物件的另外一个别名。

        iOS班的课程代码是CC001所以CC001就是iOS般的『属性』




        为什么我们要在这边特别说明OOP呢?阿达认为没有比用实际案例来说明更棒的方式了。没错我们再次打开Food Pin项目来说明

        第一次来的小伙伴呢,一如往常在这里准备了上一次项目进度的档案给小伙伴们。

        项目下载:http://pan.baidu.com/s/1ntuvWlr



        在RestaurantTableViewController中,我们建立了几个阵列,里面有餐厅名称,经营型态,地理位置,还有图片名称。



倘若是已经对于OOP的概念,这些资料可以被视为餐厅属性,因此取代将这些资料放在各个阵列中最好的方式,就是建立一个 Restaurnat 类别,可以用来储存这些资料到 Restaurant 物件的阵列中。

        简单的说就是把原本五个分散的阵列,用一个Restaurnat物件来管理。
       
        OK将修改Food Pin 专案,把资料专程使用 Restaurant类别吧。




        首先,我們建立一个 Restaurant 类别。在专案导览器的 Food Pin 档案夹的上面按下右键,选择『New File』—> 『Source』选取『Swift File』并且选择『Next』,当然也可以使用快捷键 command + N



在Restaurant.swift档案中使用以下的程式码来定义Restaurant 类别:

class Restaurant {
    var name:String = ""
    var type:String = ""
    var location:String = ""
    var image:String = ""
    var isVisited:Bool = false

    init(name:String, type:String, location:String, image:String, isVisited:Bool) {
        self.name = name
        self.type = type
        self.location = location
        self.image = image
        self.isVisited = isVisited
    }

}


在swift中,当你使用『Class』关键字定义一个类别。上面我们所提到的程式以五个属性来定义了Restaurant类别,其中包含了name,type,location,image以及isVisited属性。除了isVisited  属性是布林型态。其实都是字串型态。

        对于类别跟物件的初始化有了基本的了解之后,我们回到 Food Pin  专案,将五个阵列转换成 Restaurant 阵列。首先,从RestaurantTableViewController.swift中将阵列删除:

    var restaurantNames = ["Cafe Deadend", "Homei", "Teakha", "Cafe Loisl", "Petite Oyster", "For Kee Restaurant", "Po's Atelier", "Bourke Street Bakery", "Haigh's Chocolate", "Palomino Espresso", "Upstate", "Traif", "Graham Avenue Meats", "Waffle & Wolf", "Five Leaves", "Cafe Lore", "Confessional", "Barrafina", "Donostia", "Royal Oak", "Thai Cafe"]


    var restaurantImages = ["cafedeadend.jpg", "homei.jpg", "teakha.jpg", "cafeloisl.jpg", "petiteoyster.jpg", "forkeerestaurant.jpg", "posatelier.jpg", "bourkestreetbakery.jpg", "haighschocolate.jpg", "palominoespresso.jpg", "upstate.jpg", "traif.jpg", "grahamavenuemeats.jpg", "wafflewolf.jpg", "fiveleaves.jpg", "cafelore.jpg", "confessional.jpg", "barrafina.jpg", "donostia.jpg", "royaloak.jpg", "thaicafe.jpg"]

    var restaurantLocations = ["Hong Kong", "Hong Kong", "Hong Kong", "Hong Kong", "Hong Kong", "Hong Kong", "Hong Kong", "Sydney", "Sydney", "Sydney", "New York", "New York", "New York", "New York", "New York", "New York", "New York", "London", "London", "London", "London"]

    var restaurantTypes = ["Coffee & Tea Shop", "Cafe", "Tea House", "Austrian / Causual Drink", "French", "Bakery", "Bakery", "Chocolate", "Cafe", "American / Seafood", "American", "American", "Breakfast & Brunch", "Coffee & Tea", "Coffee & Tea", "Latin American", "Spanish", "Spanish", "Spanish", "British", "Thai"]
把这些都删除或是注解起来












作者: Kuhoku    时间: 2015-6-22 04:23
然后用下面的『restaurants』阵列取代:

var restaurants:[Restaurant] = [
        Restaurant(name: "Cafe Deadend", type: "Coffee & Tea Shop", location: "Hong Kong", image: "cafedeadend.jpg", isVisited: false),
        Restaurant(name: "Homei", type: "Cafe", location: "Hong Kong", image: "homei.jpg", isVisited: false),
        Restaurant(name: "Teakha", type: "Tea House", location: "Hong Kong", image: "teakha.jpg", isVisited: false),
        Restaurant(name: "Cafe loisl", type: "Austrian / Causual Drink", location: "Hong Kong", image: "cafeloisl.jpg", isVisited: false),
        Restaurant(name: "Petite Oyster", type: "French", location: "Hong Kong", image: "petiteoyster.jpg", isVisited: false),
        Restaurant(name: "For Kee Restaurant", type: "Bakery", location: "Hong Kong", image: "forkeerestaurant.jpg", isVisited: false),
        Restaurant(name: "Po's Atelier", type: "Bakery", location: "Hong Kong", image: "posatelier.jpg", isVisited: false),
        Restaurant(name: "Bourke Street Backery", type: "Chocolate", location: "Sydney", image: "bourkestreetbakery.jpg", isVisited: false),
        Restaurant(name: "Haigh's Chocolate", type: "Cafe", location: "Sydney", image: "haighschocolate.jpg", isVisited: false),
        Restaurant(name: "Palomino Espresso", type: "American / Seafood", location: "Sydney", image: "palominoespresso.jpg", isVisited: false),
        Restaurant(name: "Upstate", type: "American", location: "New York", image: "upstate.jpg", isVisited: false),
        Restaurant(name: "Traif", type: "American", location: "New York", image: "traif.jpg", isVisited: false),
        Restaurant(name: "Graham Avenue Meats", type: "Breakfast & Brunch", location: "New York", image: "grahamavenuemeats.jpg", isVisited: false),
        Restaurant(name: "Waffle & Wolf", type: "Coffee & Tea", location: "New York", image: "wafflewolf.jpg", isVisited: false),
        Restaurant(name: "Five Leaves", type: "Coffee & Tea", location: "New York", image: "fiveleaves.jpg", isVisited: false),
        Restaurant(name: "Cafe Lore", type: "Latin American", location: "New York", image: "cafelore.jpg", isVisited: false),
        Restaurant(name: "Confessional", type: "Spanish", location: "New York", image: "confessional.jpg", isVisited: false),
        Restaurant(name: "Barrafina", type: "Spanish", location: "London", image: "barrafina.jpg", isVisited: false),
        Restaurant(name: "Donostia", type: "Spanish", location: "London", image: "donostia.jpg", isVisited: false),
        Restaurant(name: "Royal Oak", type: "British", location: "London", image: "royaloak.jpg", isVisited: false),
        Restaurant(name: "Thai Cafe", type: "Thai", location: "London", image: "thaicafe.jpg", isVisited: false)
    ]



完成之后,Xcode 会出现几个错误警告。很明显的啦,因为我们有部分的程式内容还是参考先前那几个阵列,所以我们要将其变更几个新的 resturants阵列。

        首先我们要改变 tableView(_:numberOfRowsInSection)方法:



return self.restaurantNames.count

修改成:

return self.restaurants.count




接着更新 tableView(_:cellForRowAtIndPath:) 方法:


cell.nameLabel!.text = restaurantNames[indexPath.row]
cell.locationLabel!.text = restaurantLocations[indexPath.row]
cell.typeLabel!.text = restaurantTypes[indexPath.row]
cell.thumbnailImageView!.image = UIImage(named: restaurantImages[indexPath.row])

这几行出错的部分将他修改成:

let restaurant = restaurants [indexPath.row]

cell.nameLabel!.text = restaurant.name
cell.locationLabel!.text = restaurant.location
cell.typeLabel!.text = restaurant.type
cell.thumbnailImageView!.image = UIImage(named: restaurant.image)



因为现在所有的餐厅资讯现在都从 restaurant 物件取得。你可以使用点与罚来取得属性质。


再来将tableView(_:commitEditintStyle) 与 tableVIew

(_:editActionsForRowAtIndexPath:) 方法内的这几行程式





用这行程式取代:

self.restaurants.removeAtIndex(indexPath.row)






最后,将prepareForSegue 方法变更如下:






destinationController.restaurantImage = self.restaurantImage[indexPath.row]

修改成:

destinationController.restaurantImage = self.restaurants[indexPath.row].image





现在小伙伴们又可以执行你的APP。APP的外观感觉跟之前没有什么不同,不过我们已经重构程式,使用了Restaurant 类别。 借由类别将资料阵列转换为 Restaurant 阵列,程式的可读性也变高了!

       
        今天小伙伴也许会有『坑爹啊!一整篇下来整个APP连变都没变!』,恩! 没错!就是连变都没变,因为这个观念很重要,所以在这边特别提出来说明,将来小伙伴们的项目越来越复杂,今天是还好我们之前只有五个阵列要管理,倘若将来你的项目里面有一百个阵列呢?

        最近有越来越多的小伙伴跟阿达说有在跟着做了,真的好开心,感谢各位小伙伴的支持与爱护,让我们一起用一行一行的代码,一步一步的实现我们的梦想,我是阿达,我们下回见。




作者: Kuhoku    时间: 2015-6-22 04:33
一如往常,附上項目下載連接:http://pan.baidu.com/s/1bnxyo5h
作者: 黑妞    时间: 2015-6-22 11:42
不错!加油啊阿达!努力的人最可爱
作者: Kuhoku    时间: 2015-6-22 12:05
黑妞 发表于 2015-6-22 11:42
不错!加油啊阿达!努力的人最可爱

黑妞誇阿達可愛噎~~~~~YA
作者: 离经叛道的女子    时间: 2015-6-23 02:18
看着好复杂的说     我离大神还是太远了哎  深夜来给你赞一个
作者: Kuhoku    时间: 2015-6-23 12:24
离经叛道的女子 发表于 2015-6-23 02:18
看着好复杂的说     我离大神还是太远了哎  深夜来给你赞一个

還是太複雜了?! 那我在寫得淺白一點




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2