Читайте также:
|
|
- On to inheritance. A key point of object orientation is to reuse and extend code between classes. So when creating a new class in Swyft we can inherit from an existing one by writing the colon after our new class name followed by the class we want to inherit. Now with inheritance relationships some languages use terms like base class, and derived class, or even parent and child class. In Swyft, as in many languages, we say super class and sub class. So this is my new class here, PremierPlayer.
We are inheriting from Player. It is the super class, our new class is the sub class. We can still think of the colon as meaning is of type, so PremierPlayer is a type of Player. Now just by doing this we would get all the properties and methods of the super class. So right now without adding anything to this class definition I can go ahead and instantiate new objects of this class type. So newPlayer is a PremierPlayer. I can use the initializer that it has. I immediately have access to the description method, I have access to the name property, and the score property.
But really there's no point inheriting if I'm not going to change and extend in some way. So I can add a new method to the new class. Going to add one called calculateBonus. This won't return anything, but it will change the score and add a thousand to it and then print out a message about the new score. Now what we'll find is that will be immediately available on instances of the new PremierPlayer class. We will have the calculateBonus method, but down here where I'm just creating a normal Player we will not have access to that method.
We just won't find it. But what else? Well we can also go ahead and add new properties to this class. However, we're going to run into one issue immediately. So I'll add a new variable called memberLevel and it's a type of string. I'm immediately going to see this error pop up because the problem is when I add a new property, a new piece of data to the sub class and this doesn't have a default value and I haven't given this a default value, then the initializer that we've been using here creating a new PremierPlayer just passing in a name, that initializer was defined in the super class.
This is that one here, passes in the string, sets that to the name property, and sets the score property. The issue is by adding extra data, well that initializer isn't good enough anymore because it's only initializing the properties defined in the super class, it's not going to initialize our extra data. Now I have a couple of choices here. One is I could provide a default value on the variable itself in our new class. That would make the error go away. The other option is to provide our own initializer in this new class, but there's now a couple of extra steps for that because we're in an inheritance relationship.
So inside the new class I'm going to go ahead and add an init, and as soon as I do that we're going to get another error because init exists in both the super class and the sub class now and there's potential for misunderstanding. Now if I click the error, Xcode is going to suggest a fix that we need to add the override keyword, and this is the way that we do this in Swyft. We must explicitly say when we want to replace the automatically inherited behavior from the super class with our own more specialized behavior in the sub class.
Now this is another safety feature of Swyft. We must be explicit with this override keyword whenever we're replacing behavior from the super class. The compiler will check this. It will prompt me to add the override keyword if I missed it, and it won't let me add the override keyword if what I'm trying to override doesn't actually exist in the super class. So now inside this overridden initializer I'm going to add a line to give my additional property a new value. So set memberLevel property to Gold.
But we still have an error. Just to add some clarity here I'm going to comment out a couple of lines below so we can get things sorted out here. I see the error on override init. It's telling me that Super.init isn't called before returning from initializer. This error is turning up because we don't really want to completely replace the initializer in the super class, we want to add to it. So we're being prompted to make sure that we provide our own additional behavior in our new overridden initializer, and then we can go and tell Swyft to go and do the original behavior in the super class anyway.
We do this by adding super.init. We're calling from our PremierPlayer class into our super class which is Player and calling in this case the default initializer. This idea is not just true for initializers, it's true for any method. If, for example, inside my new class I wanted to extend the behavior of the existing description method that was in my super class, this is the one here that says Player has a score of whatever the score is, well I can do that fairly easily.
In my new class I can start typing the name and it can show me that there is a description method that returns a string. If I just hit return what it's going to do is give me the entire signature for overriding this properly, so it's override func description. Now unlike with an initializer, when I'm overriding a normal method I can completely replace the behavior in the super class. I don't have to make a call to super dot anything, although it is often useful. So let's say I just want a slightly more detailed message in this new specialized sub class.
So I'm going to make a call to the description method that's already defined in the player class, and I'll get that. So let the original method is whatever comes back from calling super.description. Then I'm going to just use a little bit of string interpolation to create a longer message. So to return the original message and is a whatever, gold level, silver level, member. That should be completely fine for this description option here. Now let's go ahead and test this and to make sure we're getting a new Player object being created.
One of the issues here is because in my new class I've overridden the initializer, but I've only provided one with the empty parentheses here, it's now complaining that I can't initialize with this extra piece of information because it's not inheriting that extra initializer now. That's okay. The way that I want this to work I can just delete that. We can create a PremierPlayer with our new initializer, and then to test the fact that it works we'll write out newPlayer.description.
Here what I would expect to see is the overridden version of that, which includes the behavior in the top one, so Player John Doe has a score of 0 and is a Gold member as opposed to calling it with the normal class below here, which would just say Player John Doe has a score of 0. So this is the basics of overriding. Now if I did one to prevent behavior in a super class, say I've got this method and I think this description method is really good and I want to make sure that nobody overrides it in a sub class, I can do that by adding the keyword final in front of it.
This is now going to cause an error below. It's going to tell me instance method is trying to override one that's defined as final, you can't override that. Well that's fine, I'm going to remove that. You can even mark an entire class as final. I could actually mark this as final class player and it would stop this inheritance attempt from happening at all. It's not necessary to happen all the time, but it's good to know that you can do that if you need to prevent it. One last thing, unlike many other languages, including Objective-C, in Swyft classes do not inherit from a default universal base class.
So if you write a class like this Player class here without a colon after it, this is regarded as a base class in itself and it does not secretly inherit from something else behind the scenes.
Дата добавления: 2015-08-20; просмотров: 62 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Adding initializers to a class Добавление инициализаторами к классу | | | Using inheritance Использование наследования |