-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathch03.html
734 lines (530 loc) · 60.7 KB
/
ch03.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Study guide for the Oracle Certified Professional, Java SE 8 Programmer Exam ">
<title>Java 8 Programmer II Study Guide: Exam 1Z0-809</title>
<link href="css/code.css" rel="stylesheet" type="text/css" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="js/common-sections.js"></script>
</head>
<body>
<div class="nav"></div>
<div class="header">
<div class="title-container">
<div class="chapter-title">
<h1><i class="chapter">Chapter THREE</i><br />
Inner Classes</h1>
<p><br /></p>
<h3 style="text-align: center;"><i>Exam Objectives</i></h3>
<p style="text-align: center;"><i>Create inner classes including static inner class, local class, nested class, and anonymous inner class.</i><br /></p>
</div>
</div>
</div>
<div class="container">
<div class="column">
<h2>Classes</h2>
<p>In Java we have classes:</p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer </span></span>{<br />
<br />
}</code></p>
<p>Classes have two types of members, attributes (or fields) and methods (or functions):<br /></p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">int</span> serialNumber;<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">executeCommand</span>()</span> {<br />
<span class="hljs-comment">// Do something<br /></span> }<br />
}</code></p>
<p>This way, our programs are a collection of classes.<br /></p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-comment">// Here goes the definition of the class<br /></span>}<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Desktop</span></span> {<br />
<span class="hljs-comment">// Here goes the definition of the class<br /></span>}<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Printer</span></span> {<br />
<span class="hljs-comment">// Here goes the definition of the class<br /></span>}<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Programmer</span></span> {<br />
<span class="hljs-comment">// Here goes the definition of the class<br /></span>}</code></p>
<h2>Inner classes<br /></h2>
<p>Java gives us flexibility in the way we can design our classes.</p>
<p>For this, there's a third type of member a class can have, an <b>INNER CLASS</b>.<br /></p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
String serialNumber;<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">executeCommand</span>()</span> { }<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
<span class="hljs-comment">// Here goes the definition of the class<br /></span> }<br />
}</code></p>
<p>Inner classes are also known as nested classes. In theory, you could have many levels of classes.</p>
<p>I have a hard time thinking about what would be the benefit of having more than one level of inner classes.</p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LevelOne</span></span> {<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LevelTwo</span></span> {<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LevelThree</span></span> {<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LevelFour</span></span> {<br />
<span class="hljs-comment"><span class="markdown">/<span class="hljs-emphasis">** Finally do something *</span>/<br /></span></span> }<br />
}<br />
}<br />
}</code></p>
<p>Another thing. We always talk about inner <b>CLASSES</b>, but actually, we can have inner <b>ABSTRACT CLASSES</b>, inner <b>INTERFACES</b>, and inner <b>ENUMS</b>.</p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br /></span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {</span> }<br />
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Pluggable</span> {</span> }<br />
<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">PORTS</span> {<br /></span> USB2, USB3, ESATA, HDMI<br />
}<br />
}</code></p>
<p>But we are going to focus on simple inner classes. There are four types of them:</p>
<ul>
<li><b>STATIC</b> inner classes<br /></li>
<li><b>NON-STATIC</b> inner classes<br /></li>
<li><b>LOCAL</b> classes<br /></li>
<li><b>ANONYMOUS</b> classes</li>
</ul>
<hr />
<h4><i>Defining a static inner class</i></h4>
<p><i><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Mouse</span></span> {<br />
}<br />
}</code></i></p>
<h4><i>Using a static inner class</i></h4>
<p><i><code class="hljs"><span class="hljs-type">Computer</span>.<span class="hljs-type">Mouse</span> m = <span class="hljs-keyword">new</span> <span class="hljs-type">Computer</span>.<span class="hljs-type">Mouse</span><span class="hljs-literal">()</span>;</code></i></p>
<p><i>Static inner classes are accessed through their enclosing class</i></p>
<hr />
<p>Static classes are <b>INDEPENDENT</b> of their enclosing class. They are like ordinary classes, only that they just happen to be inside another class.</p>
<p>In fact, you can think of the enclosing class as a kind of a package. You can import the name of the enclosing class and use the static inner class like a normal class. Just remember that the inner static class must be a <code>public</code> member so that it can be accessed from another package.</p>
<p><code class="hljs"><span class="hljs-preprocessor"><span class="hljs-keyword">import</span> com.example.Computer.*;<br /></span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span></span> {<br />
Mouse m = <span class="hljs-keyword">new</span> Mouse();<br />
<span class="hljs-comment">/** Rest of the definition */<br /></span>}</code></p>
<p>And they can also be marked as <code>private</code>, <code>protected</code> or without a modifier, so they are accessible only in the package (default accessibility).</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Component</span></span> { }<br />
<span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MotherBoard</span></span> { }<br />
<span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Slot</span></span> { }<br />
}</code></p>
<p>Of course, by being a member of a class, the static inner class have access to the other members of the enclosing class, but only if they are <b>STATIC</b>.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String serialNumber = <span class="hljs-string">"1234X"</span>;<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Mouse</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">printSN</span>()</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"MOUSE-"</span> + serialNumber);<br />
}<br />
}<br />
}</code></p>
<p>Why?</p>
<p>Think about it, if the static class is independent of its enclosing class, it doesn't need an instance of this, so only the static members could be used because they are associated with the class, not to a particular instance.</p>
<p>For that reason, a static inner class is often used as a utility class that contains common methods shared by all the objects of a class.</p>
<p>If you use the static inner class inside the class that defines it, you can use it in any method, block or constructor, no matter if it's static or not, since the inner class is not tied to a particular instance.</p>
<hr />
<h4><i>Defining a non-static inner class</i></h4>
<p><i><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span></span> {<br />
}<br />
}</code></i></p>
<h4><i>Using a non-static inner class</i></h4>
<p><i>NON-Static inner classes are accessed through an instance of their enclosing class</i></p>
<p><i><code class="hljs"><span class="hljs-type">Computer</span> c = <span class="hljs-keyword">new</span> <span class="hljs-type">Computer</span><span class="hljs-literal">()</span>;<br />
<span class="hljs-type">Computer</span>.<span class="hljs-type">HardDrive</span> hd = c.<span class="hljs-keyword">new</span> <span class="hljs-type">HardDrive</span><span class="hljs-literal">()</span>;</code></i></p>
<p><i>Check out the type of the inner class and how the new operator is used</i></p>
<hr />
<p>Non-static inner classes are just called inner classes.</p>
<p>Instances of an inner class only exist <b>WITHIN</b> an instance of the enclosing class. It's the same that when you want to use a method of a class, you <b>FIRST</b> need an instance of that class.</p>
<p>Once you have an instance of the enclosing class, you use the <code>new</code> operator in a (weird) different way than you typically use it.</p>
<p><code class="hljs"><span class="hljs-type">Computer</span> computer = <span class="hljs-keyword">new</span> <span class="hljs-type">Computer</span><span class="hljs-literal">()</span>;<br />
<span class="hljs-type">Computer</span>.<span class="hljs-type">HardDrive</span> hardDrive = computer.<span class="hljs-keyword">new</span> <span class="hljs-type">HardDrive</span><span class="hljs-literal">()</span>;</code></p>
<p>You can also use the import trick to write less, but you still need to create the inner class as always.</p>
<p><code class="hljs"><span class="hljs-preprocessor"><span class="hljs-keyword">import</span> com.example.Computer.*;<br /></span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span></span> {<br />
Computer computer = <span class="hljs-keyword">new</span> Computer();<br />
HardDrive hd = computer.<span class="hljs-keyword">new</span> HardDrive();<br />
<span class="hljs-comment">/** Rest of the definition */</span><br />
}</code></p>
<p>Another way to get an instance of an inner class is to use a method of the enclosing class to create it, avoiding that weird syntax.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span> { }<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> HardDrive <span class="hljs-title">getHardDrive</span>()</span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> HardDrive();<br />
}<br />
}</code></p>
<p>By being a member of a class, the inner class has access to the other members of the enclosing class, but this time, it <b>DOESN'T</b> matter if they are static or not.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">private</span> String brand = <span class="hljs-string">"XXX"</span>;<br />
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String serialNumber = <span class="hljs-string">"1234X"</span>;<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">printSN</span>()</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
brand + <span class="hljs-string">"-MOUSE-"</span> + serialNumber<br />
);<br />
}<br />
}<br />
}</code></p>
<p>Why?</p>
<p>Because to use the inner class, an instance of the enclosing class is required, ensuring that the non-static members exist (static members can be accessed anyway).</p>
<p>Inner classes can also be marked as <code>private</code>, <code>protected</code> or without a modifier, so they are accessible only in the package. But most of the time, since they depend on the enclosing class, they are marked as <code>private</code>.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-keyword">private</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Component</span></span> { }<br />
<span class="hljs-keyword">protected</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MotherBoard</span></span> { }<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Slot</span></span> { }<br />
}</code></p>
<p>Another rule is that inner classes <b>CANNOT</b> contain <code>static</code> members.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span> {<br />
<span class="hljs-comment">// Compile-time error here<br /></span><span class="hljs-keyword"> static</span> <span class="hljs-keyword">int</span> capacity;<br />
<span class="hljs-function"><span class="hljs-comment">// Compile-time error here<br /></span><span class="hljs-keyword"> static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInfo</span>()</span> {<br />
<span class="hljs-comment">// Definition goes here<br /></span> }<br />
}<br />
}</code></p>
<p>Static code is executed during class initialization, but you cannot initialize a non-static inner class without having an instance of the enclosing class.</p>
<p>Because an inner class belongs to <b>ONE</b> instance of the enclosing class. Having a <code>static</code> member means it can be shared across instances because the member belongs to the class, but since we are talking about an inner class that cannot be shared by many instances of the enclosing class, that is not possible.</p>
<p>The only exception is when you define a <code>final static</code> attribute. The <code>final</code> keyword makes all the difference; it makes a constant expression, but it only works with <b>ATTRIBUTES</b> and when assigning an <b>NON-NULL</b> value.</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span></span> {<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span></span> {<br />
<span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> capacity = <span class="hljs-number">120</span>; <span class="hljs-comment">// It does compile!</span><br />
<span class="hljs-comment">// Compile-time error here<br /></span><span class="hljs-keyword"> final</span> <span class="hljs-keyword">static</span> String brand = <span class="hljs-keyword">null</span>;<br />
<span class="hljs-comment">// Compile-time error here<br /></span><span class="hljs-function"><span class="hljs-keyword"> final</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInfo</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-comment">// Definition goes here<br /></span> }<br />
}<br />
}</code></p>
<hr />
<h4><i>Defining a local class</i></h4>
<p><i><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>()</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
}<br />
}<br />
}</code></i></p>
<h4><i>Using a local class</i></h4>
<p><i>Local classes can only be used inside the method or block that defines them</i></p>
<p><i><code class="hljs"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>()</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Core</span> { }<br />
Core core = <span class="hljs-keyword">new</span> Core();<br />
}</code></i></p>
<hr />
<p>Local classes are local because they can only be used in the method or block where they are declared. Blocks are practically anything between curly braces.</p>
<p><code class="hljs">void <span class="hljs-function"><span class="hljs-keyword">method</span><span class="hljs-params">()</span> {<br />
<span class="hljs-keyword">class</span> MethodLocalClass { }<br />
MethodLocalClass mlc = <span class="hljs-keyword">new</span> MethodLocalClass<span class="hljs-params">()</span>;<br /></span> <span class="hljs-keyword">if</span> ( <span class="hljs-number">1</span> == <span class="hljs-number">1</span> ) {<br />
<span class="hljs-keyword">class</span> IfLocalClass { }<br />
IfLocalClass ilc = <span class="hljs-keyword">new</span> IfLocalClass();<br />
}<br />
<span class="hljs-keyword">while</span> ( <span class="hljs-keyword">true</span> ) {<br />
<span class="hljs-keyword">class</span> WhileLocalClass { }<br />
WhileLocalClass wlc = <span class="hljs-keyword">new</span> WhileLocalClass();<br />
}<br />
}</code></p>
<p>Also, notice where the instances of the local classes are created. The local class has to be used <b>BELOW</b> its definition. Otherwise, the compiler won't be able to find it.</p>
<p>Because a local inner class is not a member of a class, it <b>CANNOT</b> be declared with an access level, and it wouldn't make sense anyway since they are only accessible where they are declared. However, a local class can be declared as abstract or final (but not at the same time).</p>
<p>Local classes require an instance of their enclosing class so the method or block in which they are defined can be executed. For this reason, they can access the members of the enclosing class, but they cannot declare static members (only static final attributes), just like inner classes.</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">private</span> String serialNumber = <span class="hljs-string">"1234XX"</span>;<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>()</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
Processor() {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"Processor #1 of computer "</span> +<br />
serialNumber<br />
);<br />
}<br />
}<br />
}<br />
}</code></p>
<p>If the local class is declared inside a method, it can access the variables and parameters of the method <b>ONLY</b> if they are declared final or are effectively final.</p>
<p><i>Effectively final</i> is a term that means that a variable or parameter is not changed after it's initialized, even if its declaration does not use the <code>final</code> keyword.</p>
<p>Why?</p>
<p>Because an instance of a local class can be alive even after the method or block in which it is defined has finished its execution (for example, if a reference is saved in an object with greater scope). For this reason, the local class must keep an internal copy of the variables it uses, and the only way to ensure that both copies always hold the same value it's by making the variable <code>final</code>.</p>
<p>So, the following code is valid because <code>taskName</code> is declared <code>final</code> while <code>n</code> doesn't change and is considered <i>effectively final</i>.</p>
<p><code class="hljs"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> n</span>)</span> {<br />
final String taskName = <span class="hljs-string">"Task #1"</span>;<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
Processor() {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"Processor "</span> + n +<br />
<span class="hljs-string"> " processing "</span> + taskName<br />
);<br />
}<br />
}<br />
}</code></p>
<p>But if we modify the value of <code>n</code> somewhere, an error will be generated.</p>
<p><code class="hljs"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> n</span>)</span> {<br />
final String taskName = <span class="hljs-string">"Task #1"</span>;<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
Processor() {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"Processor "</span> + n + <span class="hljs-comment">// Compile-time error<br /></span> <span class="hljs-string">" processing "</span> + taskName<br />
);<br />
}<br />
}<br />
n = <span class="hljs-number">4</span>;<br />
}</code></p>
<p><i>Effectively final</i> is only concerned with references, not objects or their content, because at the end of the day, we are referencing the same object.</p>
<p><code class="hljs"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> n</span>)</span> {<br />
StringBuffer taskName = <span class="hljs-keyword">new</span> StringBuffer(<span class="hljs-string">"Task #1"</span>);<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">Processor</span> {<br />
Processor() {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"Processor "</span> + n +<br />
<span class="hljs-string">" processing "</span> + taskName <span class="hljs-comment">// It does compile!<br /></span> );<br />
}<br />
}<br />
taskName.append(<span class="hljs-string">"1"</span>); <span class="hljs-comment">// This is valid!<br /></span> <span class="hljs-comment">//Uncommenting the following line will generate an error<br /></span> <span class="hljs-comment">//taskName = new StringBuffer("Task #2");<br /></span> }</code></p>
<p>If you're still not sure about a declaration being <i>effectively final</i>, try adding the <code>final</code> modifier to it. If the program continues to behave in the same way, then the declaration is <i>effectively final</i>.</p>
<p>If the class is declared in a static method, static rules also apply, meaning that the local class only has access to the static members of the enclosing class.</p>
<hr />
<h4><i>Defining an anonymous class</i></h4>
<p><i>The new operator is followed by the name of an interface or a class and the arguments to a constructor (or empty parentheses if it's an interface)</i></p>
<p><i><code class="hljs">Computer comp = <span class="hljs-keyword">new</span> Computer() {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-comment">// Here goes the definition<br /></span> }<br />
};</code></i></p>
<p><i>Look how it ends with a semicolon, like any other Statement in java</i></p>
<p><i>The body of the class implements the interface or extends the class referenced</i></p>
<hr />
<p>An anonymous class is called that way because it doesn't have a name. However, an anonymous class expression doesn't declare a new class. It either <b>IMPLEMENTS</b> an existing interface or <b>EXTENDS</b> an existing class. So</p>
<p><code class="hljs"><span class="hljs-tag">new</span> <span class="hljs-tag">Computer</span>() { }</code></p>
<p>is like writing</p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> [<span class="hljs-title">NO_NAME_CLASS</span>] <span class="hljs-keyword">extends</span> <span class="hljs-title">Computer</span></span> { }</code></p>
<p>And if we're working with an interface</p>
<p><code class="hljs"><span class="hljs-keyword">new</span> Runnable() { }</code></p>
<p>is like writing</p>
<p><code class="hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> [<span class="hljs-title">NO_NAME_CLASS</span>] <span class="hljs-keyword">implements</span> <span class="hljs-title">Runnable</span></span> { }</code></p>
<p>Also, an anonymous class can be used in a declaration or a method call.</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">start</span>(<span class="hljs-params">Computer c</span>)</span> {<br />
<span class="hljs-comment">// Definition goes here<br /></span> }<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String args[]</span>)</span> {<br />
Program program = <span class="hljs-keyword">new</span> Program();<br />
program.start(<span class="hljs-keyword">new</span> Computer() {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span>()</span> { <span class="hljs-comment">/** Redefinition goes here */</span> }<br />
});<br />
}<br />
}</code></p>
<p>Since they don't have a name (well, actually the compiler gives them a random name when it creates the <code>.class</code> file), anonymous classes can't have <b>CONSTRUCTORS</b>. If you want to run some initializing code, you have to do it with an initializer block.</p>
<p><code class="hljs">Computer t = <span class="hljs-keyword">new</span> Computer() {<br />
{<br />
<span class="hljs-comment">// Initializing code<br /></span> }<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">process</span><span class="hljs-params">()</span></span> { <span class="hljs-comment">/** Redefinition goes here */</span> }<br />
};</code></p>
<p>Because anonymous classes are a type of local classes, they have the same rules:</p>
<ul>
<li style="list-style: none"> </li>
<li>They can access the members of their enclosing class<br /></li>
<li style="list-style: none"> </li>
<li>They cannot declare <code>static</code> members (only if they are <code>final</code> <code>static</code> variables)<br /></li>
<li style="list-style: none"> </li>
<li>They can only access local variables (variables or parameters defined in a method) if they are final or <i>effectively final</i>.<br /></li>
</ul>
<p>But one thing you have to be careful with, is inheritance.</p>
<p>When you use an anonymous class (a subclass object), you're using a superclass reference. With this reference, you can use the attributes and methods declared in that type.</p>
<p>But what happens when you declare a new method on the anonymous class?</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-keyword">Task</span> {<br />
<span class="hljs-keyword">void</span> doIt() {<br />
<span class="hljs-comment">/** Here goes the definition */<br /></span> }<br />
}<br />
<span class="hljs-keyword">class</span> Launcher {<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> main(String args[]) {<br />
<span class="hljs-keyword">Task</span> <span class="hljs-keyword">task</span> = <span class="hljs-keyword">new</span> <span class="hljs-keyword">Task</span>() {<br />
<span class="hljs-keyword">void</span> redoIt() {<br />
<span class="hljs-comment">/** Here goes the definition */<br /></span> }<br />
};<br />
<span class="hljs-keyword">task</span>.doIt(); <span class="hljs-comment">// It's OK<br /></span> <span class="hljs-keyword">task</span>.redoIt(); <span class="hljs-comment">// Compile-time error!<br /></span> }<br />
}</code></p>
<p>The program will fail. The reference doesn't know about the method <code>redoIt()</code> because it's not defined in the superclass.</p>
<p>Typically, you would cast the type to the subclass where the new method is defined.</p>
<p><code class="hljs"><span class="hljs-type">SubClass</span> <span class="hljs-class"><span class="hljs-keyword">object</span> =</span> (<span class="hljs-type">SubClass</span>) objectWithSuperClassReference;<br />
<span class="hljs-class"><span class="hljs-keyword">object</span>.<span class="hljs-title">methodOnlyDefinedInTheSubclass</span>(</span>);</code></p>
<p>But with an anonymous class, how does the cast is done?</p>
<p>It can't be done; the class has no name, so there is no way we can use the methods defined in the declaration of the anonymous class. We can only use the methods defined in the <b>SUPERCLASS</b> (be it an interface or class).</p>
<p>Using an anonymous class is mostly about style. If the class has a short body, it only implements one interface (if we're working with interfaces), it doesn't declare new members, and the syntax makes your code clearer, you should consider using it instead of a local or an inner class.</p>
<h2>Shadowing</h2>
<p>An important concept to take into account when working with inner classes (of any type) is what happens when a member of the inner class has the same name of a member of the enclosing class.</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> Computer {<br />
<span class="hljs-keyword">private</span> String serialNumber = <span class="hljs-string">"1234XXX"</span>;<br />
<span class="hljs-keyword">class</span> HardDrive {<br />
<span class="hljs-keyword">private</span> String serialNumber = <span class="hljs-string">"1234DDD"</span>;<br />
<span class="hljs-keyword">void</span> printSN(String serialNumber) {<br />
System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"SN: "</span> + serialNumber);<br />
}<br />
}<br />
}</code></p>
<p>In this case, the parameter <code>serialNumber</code> shadows the instance variable <code>serialNumber</code> of <code>HardDrive</code> that in turn, shadows the <code>serialNumber</code> of <code>Computer</code>.</p>
<p>As it's coded, the method <code>printSN()</code> will print its argument. A shadowed declaration needs something else to be properly referred.</p>
<p>We know that when an object wants to refer to itself, we need to use the keyword <code>this</code>.</p>
<p>So, if we use <code>this</code> inside an inner class, it will refer to the inner class itself.</p>
<p>If we need to reference the enclosing class, inside the inner class we can also use <code>this</code>, but in this way <code>NameOfTheEnclosingClass.this</code>.</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">Computer</span> {<br />
<span class="hljs-keyword">private</span> String serialNumber = <span class="hljs-string">"1234XXX"</span>;<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">HardDrive</span> {<br />
<span class="hljs-keyword">private</span> String serialNumber = <span class="hljs-string">"1234DDD"</span>;<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">printSN</span>(<span class="hljs-params">String serialNumber</span>)</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"SN: "</span> + serialNumber<br />
);<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"HardDrive SN: "</span> + <span class="hljs-keyword">this</span>.serialNumber<br />
);<br />
System.<span class="hljs-keyword">out</span>.println(<br />
<span class="hljs-string">"Computer SN: "</span> +<br />
Computer.<span class="hljs-keyword">this</span>.serialNumber<br />
);<br />
}<br />
}<br />
}</code></p>
<p>Since it may cause confusion, it's better to avoid it and use descriptive variable names.</p>
<div style="page-break-after:always;"></div>
<h2>Key Points</h2>
<ul>
<li>Inner classes are declared inside another class. There are four types of them: static, non-static, local and anonymous classes.<br /></li>
<li>Static classes are just inner classes marked with the <code>static</code> keyword. However, they behave more like a top-level class than an inner class.<br /></li>
<li>You don't need an instance of the enclosing class to instantiate a static class:<br />
<code class="hljs"><span class="hljs-type">EnclosingClass</span>.<span class="hljs-type">StaticClass</span> sc = <span class="hljs-keyword">new</span> <span class="hljs-type">EnclosingClass</span>.<span class="hljs-type">StaticClass</span><span class="hljs-literal">()</span>;</code></li>
<li>A static class cannot access non-static members of the enclosing class since it doesn't require having an instance of the enclosing class to use it.<br /></li>
<li>A (non-static) inner class is like any other member of the enclosing class so that it can be marked with any access modifier.<br /></li>
<li>Outside the enclosing class' instance methods or blocks, to instantiate an inner class, you must first create an instance of the enclosing class and then:<br />
<code class="hljs"><span class="hljs-type">EnclosingClass</span> ec = <span class="hljs-keyword">new</span> <span class="hljs-type">EnclosingClass</span><span class="hljs-literal">()</span>;<br />
<span class="hljs-type">EnclosingClass</span>.<span class="hljs-type">InnerClass</span> ic = ec.<span class="hljs-keyword">new</span> <span class="hljs-type">InnerClass</span><span class="hljs-literal">()</span>;</code></li>
<li>A local class is defined within a method or block of the enclosing class.<br /></li>
<li>The only modifiers that apply to a local class are abstract and final (but not at the same time).<br /></li>
<li>You can only use a local class in the method or block where you define it, and only after its declaration.<br /></li>
<li>A local class can access the members of a class just like any other member of the class (static rules still apply).<br /></li>
<li>However, a local class can only access the parameters and local variables of a method if they are final or <i>effectively final</i>.<br /></li>
<li><i>Effectively final</i> means that a variable cannot be modified after its initialization, even if it's not explicitly marked as <code>final</code>.<br /></li>
<li>Anonymous classes have no name, and they either extend an existing class or implement an interface:<br />
<code class="hljs">ExistingClass ac = <span class="hljs-keyword">new</span> ExistingClass() {<br />
<span class="hljs-comment"> // Definition goes here</span><br />
};</code></li>
<li>Anonymous classes cannot have constructors.<br /></li>
<li>Anonymous classes have the same rules as local classes regarding accessing members of the enclosing class and local variables of a method.<br /></li>
<li>The only methods you can call on an anonymous class are those defined in the reference type (the superclass or the interface), even though anonymous classes can define their own methods.<br /></li>
</ul>
<div style="page-break-after:always;"></div>
<h2>Self Test</h2>
<p>1. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_1</span> {<br />
<span class="hljs-keyword">interface</span> <span class="hljs-title">ITest</span> { <span class="hljs-comment">// 1<br /></span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">m</span>()</span>;<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String args[]</span>)</span> {<br />
ITest t = <span class="hljs-keyword">new</span> ITest() { <span class="hljs-comment">// 2<br /></span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">m</span>()</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"m()"</span>);<br />
}<br />
};<br />
t.m();<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>m()</code><br /> B. Compilation fails on the declaration marked as <code>// 1</code><br /> C. Compilation fails on the declaration marked as <code>// 2</code><br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>2. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-type">Question_3_2</span> {<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">void</span> main(<span class="hljs-type">String</span> args[]) {<br />
<span class="hljs-type">Question_3_2</span> q = new <span class="hljs-type">Question_3_2</span>();<br />
<span class="hljs-type">int</span> i = <span class="hljs-number">2</span>;<br />
q.<span class="hljs-keyword">method</span>(i);<br />
i = <span class="hljs-number">4</span>;<br />
}<br />
<span class="hljs-keyword">void</span> <span class="hljs-keyword">method</span>(<span class="hljs-type">int</span> i) {<br />
class A {<br />
<span class="hljs-type">void</span> helper() {<br />
<span class="hljs-type">System</span>.<span class="hljs-keyword">out</span>.println(i);<br />
}<br />
}<br />
<span class="hljs-keyword">new</span> A().helper();<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. Compilation fails<br /> B. <code>2</code><br /> C. <code>4</code><br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>3. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> Question_3_3 {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
Question_3_3 q = <span class="hljs-keyword">new</span> Question_3_3() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sum</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span> { <span class="hljs-comment">// 1<br /></span> <span class="hljs-keyword">return</span> a + b;<br />
}<br />
};<br />
q.sum(<span class="hljs-number">2</span>,<span class="hljs-number">6</span>); <span class="hljs-comment">// 2<br /></span> }<br />
}</code></p>
<p>What is the result?<br /> A. Compilation fails on the declaration marked as <code>// 1</code><br /> B. Compilation fails on the line marked as <code>// 2</code><br /> C. <code>8</code><br /> D. Nothing is printed</p>
<div style="page-break-after:always;"></div>
<p>4. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_4</span> {<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Inner</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doIt</span>()</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"doIt()"</span>);<br />
}<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>)</span> {<br />
Question_3_4.Inner i = <span class="hljs-keyword">new</span> Inner();<br />
i.doIt();<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. Compilation fails because an inner class cannot be <code>static</code>.<br /> B. Compilation fails because the <code>Inner</code> class is instantiated incorrectly inside method <code>main</code>.<br /> C. Compilation fails because the method <code>doIt</code> cannot be called in main because it is declared as <code>private</code><br /> D. The program prints <code>doIt()</code></p>
<div style="page-break-after:always;"></div>
<p>5. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">B</span> {<br />
<span class="hljs-keyword">class</span> <span class="hljs-title">C</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">go</span>()</span> {<br />
System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"go!"</span>);<br />
}<br />
}<br />
}<br />
}<br />
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_5</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>)</span> {<br />
A a = <span class="hljs-keyword">new</span> A();<br />
A.B b = a.new A.B(); <span class="hljs-comment">// 1<br /></span> B.C c = b.new C(); <span class="hljs-comment">// 2<br /></span> c.go(); <span class="hljs-comment">// 3<br /></span> }<br />
}</code></p>
<p>What is the result?<br /> A. Compilation first fails on the line <code>// 1</code><br /> B. Compilation first fails on the line <code>// 2</code><br /> C. Compilation fails on the line <code>// 3</code><br /> D. <code>go!</code> is printed</p>
<div style="page-break-after:always;"></div>
<p>6. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_6</span> {<br />
<span class="hljs-keyword">private</span> <span class="hljs-keyword">class</span> <span class="hljs-title">A</span> { <span class="hljs-comment">// 1<br /></span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">plusTwo</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> n</span>)</span> {<br />
<span class="hljs-keyword">return</span> n + <span class="hljs-number">2</span>;<br />
}<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>)</span> {<br />
Question_3_6.A a = <span class="hljs-keyword">new</span> A(); <span class="hljs-comment">// 2<br /></span> System.<span class="hljs-keyword">out</span>.println(a.plusTwo(<span class="hljs-number">3</span>));<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. Compilation fails on the line <code>// 1</code><br /> B. Compilation fails on the line <code>// 2</code><br /> C. <code>5</code><br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>7. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_7</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span></span> { <span class="hljs-comment">// 1<br /></span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">m</span><span class="hljs-params">()</span></span> {<br />
System.out.println(<span class="hljs-string">"m()"</span>);<br />
}<br />
}<br />
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AA</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">A</span></span> { } <span class="hljs-comment">// 2<br /></span> }<br />
}</code></p>
<p>What change would make this code compile?<br /> A. Remove the <code>abstract</code> keyword on the line <code>// 1</code><br /> B. Add the <code>public</code> keyword on the line <code>// 1</code><br /> C. Remove the <code>public</code> keyword on the line <code>// 2</code><br /> D. None. This code compiles correctly</p>
<div style="page-break-after:always;"></div>
<p>8. Given:</p>
<p><code class="hljs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Question_3_8</span> {<br />
<span class="hljs-keyword">int</span> i = <span class="hljs-number">2</span>;<br />
<span class="hljs-keyword">interface</span> <span class="hljs-title">A</span> {<br />
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">add</span>()</span>;<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> A <span class="hljs-title">create</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> i</span>)</span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> A() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span>()</span> {<br />
<span class="hljs-keyword">return</span> i + <span class="hljs-number">4</span>;<br />
}<br />
};<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>)</span> {<br />
A a = <span class="hljs-keyword">new</span> Question_3_8().create(<span class="hljs-number">8</span>);<br />
System.<span class="hljs-keyword">out</span>.println(a.add());<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>6</code><br /> B. <code>12</code><br /> C. Compilation fails<br /> D. An exception occurs at runtime</p>
<div class="answers">
<a href="ch03a.html" target="_blank">Open answers page</a>
</div>
<div class="book-info"></div>
<div class="linkbox">
<div class="previous">
<a href="ch02.html">02. Inheritance and Polymorphism</a>
</div>
<div class="next">
<a href="ch04.html">04. Interfaces</a>
</div>
<div style="clear:both;"></div>
</div>
</div>
</div>
</body>
</html>