ජාවාහි අභ්යන්තර පන්තියක් සහ ස්ථිතික කැදැලි පන්තියක් අතර ඇති ප්රධාන වෙනස කුමක්ද? මෙයින් එකක් තෝරාගැනීමේදී සැලසුම් / ක්රියාත්මක කිරීම වැදගත් කාර්යභාරයක් ඉටු කරයිද?
ජාවාහි අභ්යන්තර පන්තියක් සහ ස්ථිතික කැදැලි පන්තියක් අතර ඇති ප්රධාන වෙනස කුමක්ද? මෙයින් එකක් තෝරාගැනීමේදී සැලසුම් / ක්රියාත්මක කිරීම වැදගත් කාර්යභාරයක් ඉටු කරයිද?
Answers:
සිට ජාවා නිබන්ධනය :
කැදැලි පන්ති කොටස් දෙකකට බෙදා ඇත: ස්ථිතික හා ස්ථිතික නොවන. ස්ථිතික ලෙස ප්රකාශයට පත් කරන ලද කැදැලි පන්ති හුදෙක් ස්ථිතික කැදැලි පන්ති ලෙස හැඳින්වේ. ස්ථිතික නොවන කැදැලි පන්ති අභ්යන්තර පන්ති ලෙස හැඳින්වේ.
සංවෘත පන්තියේ නම භාවිතා කරමින් ස්ථිතික කැදැලි පන්ති වෙත ප්රවේශ වේ:
OuterClass.StaticNestedClass
උදාහරණයක් ලෙස, ස්ථිතික කැදැලි පන්තිය සඳහා වස්තුවක් නිර්මාණය කිරීම සඳහා, මෙම වාක්ය ඛණ්ඩය භාවිතා කරන්න:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
අභ්යන්තර පංතියක නිදසුන් වන වස්තූන් පවතින්නේ බාහිර පන්තියේ අවස්ථාවක් තුළ ය. පහත සඳහන් පන්ති සලකා බලන්න:
class OuterClass {
...
class InnerClass {
...
}
}
ඉනර් ක්ලාස් හි නිදසුනක් පැවතිය හැක්කේ uter ටර් ක්ලාස් හි නිදසුනක් තුළ පමණක් වන අතර එය සම්බන්ධ කර ඇති ක්රම සහ ක්ෂේත්ර වෙත access ජු ප්රවේශයක් ඇත.
අභ්යන්තර පංතියක් ස්ථාපනය කිරීම සඳහා, ඔබ පළමුව බාහිර පන්තිය ක්ෂණිකව ක්රියාත්මක කළ යුතුය. ඉන්පසු, මෙම වාක්ය ඛණ්ඩය සමඟ පිටත වස්තුව තුළ අභ්යන්තර වස්තුව සාදන්න:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
බලන්න: ජාවා නිබන්ධනය - කැදැලි පන්ති
සංක්ෂිප්ත නිදසුනක් නොමැතිව අභ්යන්තර පංතියක් වැනි දෙයක් ද ඇති බව සම්පූර්ණ සටහන සඳහා :
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
මෙන්න, ස්ථිතික සන්දර්භයක් තුළ අර්ථ දක්වාnew A() { ... }
ඇති අභ්යන්තර පංතියක් වන අතර එයට සංවෘත අවස්ථාවක් නොමැත.
import OuterClass.StaticNestedClass;
එසේ නම්, පන්ති අදාල පමණක් OuterClass ලෙස.
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
?
මෙම ජාවා ටියුට් එකේ කියන :
පාරිභාෂිතය: කැදැලි පන්ති කොටස් දෙකකට බෙදා ඇත: ස්ථිතික හා ස්ථිතික නොවන. ස්ථිතික ලෙස ප්රකාශයට පත් කරන ලද කැදැලි පන්ති හුදෙක් ස්ථිතික කැදැලි පන්ති ලෙස හැඳින්වේ. ස්ථිතික නොවන කැදැලි පන්ති අභ්යන්තර පන්ති ලෙස හැඳින්වේ.
පොදුවේ ගත් කල, බොහෝ වැඩසටහන්කරුවන් විසින් "කැදැල්ල" සහ "අභ්යන්තරය" යන වචන එකිනෙකට වෙනස් ලෙස භාවිතා කරනු ලැබේ, නමුත් මම අභ්යන්තර හා ස්ථිතික යන දෙකම ආවරණය වන නිවැරදි "කැදැලි පන්තිය" යන යෙදුම භාවිතා කරමි.
පංති අනන්ත ලෙස කැදැල්ල කළ හැකිය , උදා: පංතියේ බී පන්තියේ සී පන්තිය අඩංගු බී පන්තිය අඩංගු විය හැකිය. කෙසේ වෙතත්, සාමාන්යයෙන් නරක මෝස්තරයක් බැවින් පන්ති කැදැල්ල එක් මට්ටමකට වඩා දුර්ලභ වේ.
ඔබට කැදැලි පන්තියක් නිර්මාණය කිරීමට හේතු තුනක් තිබේ:
ඇත ජාවා පිලිතුරු කැදැලි පන්ති වර්ග හතරක් . කෙටියෙන් කිවහොත්, ඒවා නම්:
වැඩි විස්තර විස්තර කිරීමට මට ඉඩ දෙන්න.
ස්ථිතික පංති යනු තේරුම් ගැනීමට පහසුම වර්ගයකි, මන්ද ඒවාට අඩංගු පංතියේ අවස්ථා සමඟ කිසිදු සම්බන්ධයක් නැත.
ස්ථිතික පංතිය යනු වෙනත් පන්තියක ස්ථිතික සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කරන ලද පන්තියකි. අනෙකුත් ස්ථිතික සාමාජිකයන් මෙන්ම, එවැනි පංතියක් ඇත්ත වශයෙන්ම එහි ඇති අවකාශය එහි නාම අවකාශය ලෙස භාවිතා කරන එල්ලුම් ගහක් පමණි , උදා: පීසා පැකේජයේ පන්තියේ රයිනෝ හි ස්ථිතික සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කරන ලද එළු පන්තිය පීසා නමින් හැඳින්වේ. රයිනෝ.ගෝට් .
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
අවංකවම, ස්ථිතික පංති යනු කිසිසේත්ම වැදගැම්මකට නැති ලක්ෂණයකි. ස්ථිතික පංතියක් නිර්මාණය කිරීමට ඇති එකම සැබෑ හේතුව නම්, එවැනි පංතියකට එහි අඩංගු පංතියේ පෞද්ගලික ස්ථිතික සාමාජිකයින්ට ප්රවේශය තිබීමයි, නමුත් මෙය ස්ථිතික පංති අංගය පැවතීම සඳහා ඉතා අශෝභන සාධාරණීකරණය කිරීමක් ලෙස මට පෙනේ.
අභ්යන්තර පංතිය යනු වෙනත් පන්තියක ස්ථිතික නොවන සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කරන ලද පන්තියකි:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
ස්ථිතික පංතියක් මෙන්, අභ්යන්තර පංතිය එහි සුදුසුකම් ලත් පංතියේ නම වන පීසා.රිනෝ.ගෝට් මගින් හැඳින්වේ , නමුත් අඩංගු පන්තිය තුළ එය එහි සරල නාමයෙන් දැනගත හැකිය. කෙසේ වෙතත්, අභ්යන්තර පන්තියේ සෑම අවස්ථාවක එහි අඩංගු පන්තියේ යම් උදාහරණයක් බැඳී: ඉහත ද එළු නිර්මාණය ජෙරී , නිසැකයෙන්ම බැඳී රයිනෝ උදාහරණයක් මෙම දී ජෙරී . එසේ නොමැති නම්, අපි ඒ හා සම්බන්ධ කරමු එළු ක්ෂණිකව ක්රියාත්මක කරන විට රයිනෝ උදාහරණය පැහැදිලි කරන්නෙමු :
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(ඔබ අමුතු අළුත් එළුවා ලෙස අභ්යන්තර වර්ගය සඳහන් කරන බව සැලකිල්ලට ගන්න වාක්ය ඛණ්ඩයේ : ජාවා රයිනෝ කොටසෙන් අඩංගු වර්ගය අනුමාන කරයි . ඔව්, නව රයිනෝ.ගෝට් () ද මා වෙත වැඩි හැඟීමක් ඇති වනු ඇත.)
ඉතින් මෙය අපට ලැබෙන්නේ කුමක්ද? හොඳයි, අභ්යන්තර පංතියේ නිදර්ශනයට අඩංගු පංති නිදර්ශනයේ සාමාජිකයින්ට ප්රවේශය ඇත. මෙම ආකෘති උදාහරණයක් සාමාජිකයන් ඇතුළු පන්ති ඇතුලේ සඳහන් වේ හරහා පමණක් තම සරල නම්, නැති හරහා මෙම ( මෙම අභ්යන්තර පන්තිය තුල අභ්යන්තර පන්ති උදාහරණයේ දී, සම්බන්ධ අඩංගු පන්ති අවස්ථාව නොවේ යන්නෙන්):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
අභ්යන්තර පන්ති, ඔබ යොමු වේ මෙම ලෙස අඩංගු පන්තියේ Rhino.this , ඔබ භාවිතා කළ හැකිය මේ , එහි සාමාජිකයන් වෙත යොමු කිරීමට Rhino.this.barry උදා .
දේශීය අභ්යන්තර පංතියක් යනු ක්රමවේදයක ශරීරය තුළ ප්රකාශිත පන්තියකි. එවැනි පංතියක් දන්නේ එහි අඩංගු ක්රමවේදය තුළ පමණි, එබැවින් එය ක්ෂණිකව කළ හැකි අතර එහි සාමාජිකයින්ට එහි අඩංගු ක්රමයට ප්රවේශ විය හැකිය. වාසිය නම් දේශීය අභ්යන්තර පංතියේ නිදසුනක් සමඟ බැඳී ඇති අතර එය අඩංගු ක්රමයේ අවසාන දේශීය විචල්යයන්ට ප්රවේශ විය හැකිය. නිදසුන එහි අඩංගු ක්රමයේ අවසාන දේශීයයක් භාවිතා කරන විට, විචල්යය විෂය පථයෙන් බැහැරව ගියද, එය නිර්මාණය කරන අවස්ථාවේ දී එහි අගය රඳවා තබා ගනී (මෙය effectively ලදායි ලෙස ජාවාහි ගොරහැඩි, වසා දැමීමේ සීමිත අනුවාදය වේ).
දේශීය අභ්යන්තර පංතියක් පන්තියක හෝ පැකේජයක සාමාජිකයෙකු නොවන බැවින් එය ප්රවේශ මට්ටමකින් ප්රකාශයට පත් නොකෙරේ. (කෙසේ වෙතත්, එහි සාමාජිකයින්ට සාමාන්ය පන්තියක මෙන් ප්රවේශ මට්ටම් ඇති බව පැහැදිලිය.)
දේශීය අභ්යන්තර පංතියක් නිදර්ශන ක්රමයකින් ප්රකාශයට පත් කරන්නේ නම්, අභ්යන්තර පංතිය පිළිබඳ ක්ෂණික දර්ශනයක්, නිදසුන නිර්මාණය කරන අවස්ථාවේ දී අඩංගු ක්රමවේදය විසින් දරණ ලද සිද්ධියට බැඳී ඇති අතර , එම නිසා පන්තියේ නිදර්ශන සාමාජිකයින්ට නිදසුනක් ලෙස ප්රවේශ විය හැකිය. අභ්යන්තර පන්තිය. දේශීය අභ්යන්තර පන්ති හුදෙක් instantiated ඇත හරහා එහි නම, උදා: දේශීය අභ්යන්තර පන්ති කැට් ලෙස instantiated ඇත නව කැට් () ඔබ බලාපොරොත්තු විය හැකි පරිදි, නව this.Cat ().
නිර්නාමික අභ්යන්තර පංතිය යනු දේශීය අභ්යන්තර පංතියක් ලිවීමේ සින්ටැක්ටිකල් පහසු ක්රමයකි. බොහෝ විට, දේශීය අභ්යන්තර පංතියක් එහි අඩංගු ක්රමවේදය ක්රියාත්මක වන සෑම අවස්ථාවකම එක් වරක් පමණක් ක්ෂණිකව ක්රියාත්මක වේ. එසේ නම්, දේශීය අභ්යන්තර පංතියේ අර්ථ දැක්වීම සහ එහි තනි ස්ථාපනය එක් පහසු වාක්ය ඛණ්ඩයකට ඒකාබද්ධ කළ හැකි නම් හොඳයි, පංතිය සඳහා නමක් සිතීමට අපට අවශ්ය නොවන්නේ නම් එයද හොඳය. ඔබේ කේතයේ නම් සඳහන් කිරීම වඩා හොඳය). නිර්නාමික අභ්යන්තර පංතියක් මේ දෙකටම ඉඩ දෙයි:
new *ParentClassName*(*constructorArgs*) {*members*}
මෙය ParentClassName විස්තාරණය කරන නම් නොකළ පන්තියක නව අවස්ථාවක් ලබා දෙන ප්රකාශනයකි . ඔබට ඔබේම ඉදිකිරීම්කරුවෙකු සැපයිය නොහැක; ඒ වෙනුවට, එකක් ව්යංගයෙන් සපයනු ලබන අතර එය හුදෙක් සුපිරි ඉදිකිරීම්කරු ලෙස හැඳින්වේ, එබැවින් සපයන තර්ක සුපිරි ඉදිකිරීම්කරුට ගැලපේ. (දෙමව්පියන් බහු ඉදිකිරීම්කරුවන් සිටී නම්, විස්තරාත්මකව ඉගෙන ගැනීමට කරදර නොවිය යුතු තරමක් සංකීර්ණ නීති මාලාවක් මගින් තීරණය කරනු ලබන “සරලම” “සරලම” ලෙස හැඳින්වේ - නෙට්බීන්ස් හෝ සූර්යග්රහණය ඔබට පවසන දේ කෙරෙහි අවධානය යොමු කරන්න.)
විකල්පයක් ලෙස, ක්රියාත්මක කිරීමට අතුරු මුහුණතක් නියම කළ හැකිය:
new *InterfaceName*() {*members*}
එවැනි ප්රකාශයක් නම් නොකල පංතියක නව අවස්ථාවක් නිර්මාණය කරන අතර එය වස්තුව විස්තාරණය කර අතුරුමුහුණත ක්රියාත්මක කරයි. නැවතත්, ඔබට ඔබේම ඉදිකිරීම්කරු සැපයිය නොහැක; මෙම අවස්ථාවෙහිදී, ජාවා ව්යංගයෙන් කිසිවක් නොකෙරෙන, කිසිවක් නොකරන ඉදිකිරීම්කරුවෙකු සපයයි (එබැවින් මෙම නඩුවේ කිසි විටෙකත් ඉදිකිරීම්කරුවන්ගේ තර්ක නොමැත).
ඔබට නිර්නාමික අභ්යන්තර පන්තියට ඉදිකිරීම්කරුවෙකු ලබා දිය නොහැකි වුවද, ඔබට ආරම්භක බ්ලොක් එකක් භාවිතා කිරීමට අවශ්ය ඕනෑම සැකසුමක් කළ හැකිය (ඕනෑම ක්රමයකට පිටින් {} බ්ලොක් එකක්).
නිර්නාමික අභ්යන්තර පංතියක් යනු එක් අවස්ථාවක් සමඟ දේශීය අභ්යන්තර පංතියක් නිර්මාණය කිරීමේ අඩු නම්යශීලී ක්රමයක් බව පැහැදිලිය. බහුවිධ අතුරුමුහුණත් ක්රියාත්මක කරන හෝ වස්තුව හැර වෙනත් පංතියක් විස්තාරණය කරන විට හෝ තමන්ගේම ඉදිකිරීම්කරුවෙකු නියම කරන අතුරු මුහුණත් ක්රියාත්මක කරන දේශීය අභ්යන්තර පන්තියක් ඔබට අවශ්ය නම් , ඔබ නිතිපතා නම් කරන ලද දේශීය අභ්යන්තර පන්තියක් නිර්මාණය කරමින් සිටී.
ඉහත පිළිතුරු වලින් සැබෑ වෙනස පැහැදිලි වූ බව මම නොසිතමි.
කොන්දේසි නිවැරදිව ලබා ගැනීමට පළමුව:
මාටින්ගේ පිළිතුර මෙතෙක් නිවැරදිය. කෙසේ වෙතත්, ඇත්ත ප්රශ්නය නම්: කැදැලි පන්තිය ස්ථිතික ලෙස ප්රකාශ කිරීමේ අරමුණ කුමක්ද?
ඔබ භාවිතා ස්ථිතික පිලිතුරු කැදැලි පන්ති ඔබ ඔවුන් ප්රාණඝාතය එකට අයිති හෝ පිළිතුරු පැතැලිව පන්ති පමණක්ම කවරෙ පන්තියේ භාවිතා කරන්නේ නම් නම් එකට ඔබේ පන්ති තබා ගැනීමට අවශ්ය නම්. ස්ථිතික කැදැලි පන්තියක් සහ අනෙකුත් සෑම පන්තියක් අතර අර්ථකථන වෙනසක් නොමැත.
ස්ථිතික නොවන කැදැලි පන්ති වෙනස් මෘගයෙකි. නිර්නාමික අභ්යන්තර පංති වලට සමානව, එවැනි කැදැලි පන්ති ඇත්ත වශයෙන්ම වසා දැමීම් වේ. එයින් අදහස් කරන්නේ ඔවුන් අවට ඇති විෂය පථය සහ ඒවායේ වටපිටාව ග්රහණය කර එය ප්රවේශ කළ හැකි බවයි. සමහරවිට උදාහරණයක් මගින් එය පැහැදිලි වනු ඇත. බහාලුමක මෙම කඳ කොටස බලන්න:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
මෙම අවස්ථාවේදී ඔබට ළමා අයිතමයක සිට මව් බහාලුමට යොමු කිරීමක් අවශ්ය වේ. ස්ථිතික නොවන කැදැලි පන්තියක් භාවිතා කිරීම, මෙය යම් වැඩක් නොමැතිව ක්රියා කරයි. ඔබට සින්ටැක්ස් සමඟ බහාලුමේ කොටු කිරීමේ අවස්ථාව වෙත පිවිසිය හැකිය Container.this
.
තවත් දෘ c පැහැදිලි කිරීම් පහත දැක්වේ:
ඔබ (ස්ථිතික නොවන) කැදැලි පන්තියක් සඳහා ජනනය කරන ජාවා බයිට් කේත දෙස බැලුවහොත් එය වඩාත් පැහැදිලි වනු ඇත:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
ඔබට පෙනෙන පරිදි සම්පාදකයා සැඟවුණු ක්ෂේත්රයක් නිර්මාණය කරයි Container this$0
. සංවෘත අවස්ථාව නියම කිරීම සඳහා බහාලුම් වර්ගයේ අතිරේක පරාමිතියක් ඇති ඉදිකිරීම්කරු තුළ මෙය සකසා ඇත. ඔබට මෙම පරාමිතිය ප්රභවයේ දැකිය නොහැකි නමුත් සම්පාදකයා විසින් ව්යංගයෙන් එය කැදැලි පන්තියක් සඳහා ජනනය කරයි.
මාටින්ගේ උදාහරණය
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
(බයිට් කේත වලින්) වැනි ඇමතුමකට සම්පාදනය කරනු ලැබේ
new InnerClass(outerObject)
සම්පූර්ණත්වය උදෙසා:
නිර්නාමික පංතියක් යනු ස්ථිතික නොවන කැදැලි පන්තියකට කදිම නිදසුනකි, එය එයට නමක් සම්බන්ධ කර නැති අතර පසුව එය සඳහන් කළ නොහැක.
යෙදුම් සැලසුම අනුව කැදැලි පන්තියක් සහ ස්ථිතික කැදැලි පන්තියක් අතර සැබෑ වෙනස ඉහත පිළිතුරු කිසිවක් ඔබට පැහැදිලි නොකරයි යැයි මම සිතමි.
කැදැලි පන්තියක් ස්ථිතික හෝ ස්ථිතික විය හැකි අතර සෑම අවස්ථාවකම වෙනත් පන්තියක් තුළ අර්ථ දක්වා ඇත . කැදැලි පංතියක් පැවතිය යුත්තේ සේවය කිරීම සඳහා පමණි , පන්තිය කොටු කිරීම , කැදැලි පන්තියක් වෙනත් පංති වලට ප්රයෝජනවත් නම් (කොටු කිරීම පමණක් නොව) ඉහළ මට්ටමේ පන්තියක් ලෙස ප්රකාශයට පත් කළ යුතුය.
Nonstatic Nested class : අඩංගු පංතියේ සංවෘත අවස්ථාව සමඟ ව්යංගයෙන් සම්බන්ධ වී ඇති අතර, මෙයින් අදහස් කරන්නේ සංවෘත අවස්ථාවෙහි ක්රම සහ ප්රවේශ විචල්යයන් ක්රියාත්මක කළ හැකි බවයි. අස්ථායී කැදැලි පන්තියක එක් පොදු භාවිතයක් වන්නේ ඇඩැප්ටර පන්තිය නිර්වචනය කිරීමයි.
ස්ථිතික නෙස්ටඩ් පංතිය : කොටු කිරීමේ පන්ති නිදර්ශනයට ප්රවේශ විය නොහැකි අතර ඒ සඳහා ක්රම භාවිතා කළ හැකිය, එබැවින් කූඩු පන්තියට සංවෘත පන්තියේ අවස්ථාවකට ප්රවේශය අවශ්ය නොවන විට භාවිතා කළ යුතුය. ස්ථිතික කැදැලි පන්තියේ පොදු භාවිතයක් වන්නේ පිටත වස්තුවෙහි සංරචක ක්රියාත්මක කිරීමයි.
එබැවින් සැලසුම් දෘෂ්ටි කෝණයකින් මේ දෙක අතර ඇති ප්රධාන වෙනස නම්: ස්ථිතික නොහැකි විට බහාලුම් පන්තියේ උදාහරණයට අස්ථිර කැදැලි පන්තියට ප්රවේශ විය හැකිය .
සරළව කිවහොත් අපට කූඩු පන්ති අවශ්ය වන්නේ මූලික වශයෙන් ජාවා වසා දැමීම් ලබා නොදෙන බැවිනි.
නෙස්ටඩ් පංති යනු වෙනත් සංවෘත පන්තියක ශරීරය තුළ අර්ථ දක්වා ඇති පන්ති වේ. ඒවා වර්ග දෙකකි - ස්ථිතික හා ස්ථිතික නොවන.
ඔවුන් සංවෘත පන්තියේ සාමාජිකයන් ලෙස සලකනු ලැබේ, එබැවින් ඔබට ප්රවේශ ප්රවේශයන් හතරෙන් ඕනෑම එකක් නියම කළ හැකිය - private, package, protected, public
. ඉහළ මට්ටමේ පන්ති සහිත මෙම සුඛෝපභෝගී බව අප සතුව නැත, ඒවා ප්රකාශයට පත් කළ හැකි public
හෝ පැකේජ-පෞද්ගලික පමණි.
අභ්යන්තර පංති හෝ නොබැඳි පංති වලට ඉහළ පන්තියේ අනෙකුත් සාමාජිකයින්ට ප්රවේශ විය හැකිය, ඒවා පෞද්ගලිකව ප්රකාශයට පත් කළද ස්ථිතික කැදැලි පන්තිවලට ඉහළ පන්තියේ අනෙකුත් සාමාජිකයින්ට ප්රවේශය නොමැත.
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
Inner1
අපගේ ස්ථිතික අභ්යන්තර පන්තිය වන අතර Inner2
අපගේ අභ්යන්තර පන්තිය ස්ථිතික නොවේ. ඔවුන් අතර ඇති ප්රධාන වෙනස නම්, ඔබට Inner2
බාහිරව නොමැතිව නිදසුනක් නිර්මාණය කළ නොහැකි අතර ඔබට Inner1
ස්වාධීනව වස්තුවක් නිර්මාණය කළ හැකිය .
ඔබ අභ්යන්තර පන්තිය භාවිතා කරන්නේ කවදාද?
ඇති තත්වය ගැන සිතන්න Class A
හා Class B
සම්බන්ධ වන අතර, Class B
ප්රවේශ අවශ්යතා Class A
සාමාජිකයින් සහ Class B
පමණක් අදාළ වේ Class A
. අභ්යන්තර පන්ති පින්තූරයට පැමිණේ.
අභ්යන්තර පංතියේ නිදසුනක් නිර්මාණය කිරීම සඳහා, ඔබේ බාහිර පන්තියේ උදාහරණයක් නිර්මාණය කළ යුතුය.
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
හෝ
OuterClass.Inner2 inner = new OuterClass().new Inner2();
ඔබ ස්ථිතික අභ්යන්තර පන්තිය භාවිතා කරන්නේ කවදාද?
ස්ථිතික අභ්යන්තර පංතියක් ඔබ අර්ථ දක්වනුයේ එය සංවෘත පන්තියේ / ඉහළ පන්තියේ උදාහරණය සමඟ කිසිදු සම්බන්ධයක් නොමැති බව ඔබ දන්නා විට ය. ඔබේ අභ්යන්තර පන්තිය බාහිර පන්තියේ ක්රම හෝ ක්ෂේත්ර භාවිතා නොකරන්නේ නම්, එය අවකාශය නාස්ති කිරීමක් බැවින් එය ස්ථිතික කරන්න.
උදාහරණයක් ලෙස, ස්ථිතික කැදැලි පන්තිය සඳහා වස්තුවක් නිර්මාණය කිරීම සඳහා, මෙම වාක්ය ඛණ්ඩය භාවිතා කරන්න:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
ස්ථිතික කැදැලි පන්තියක ඇති වාසිය නම් එයට වැඩ කිරීමට පන්තියේ / ඉහළ පන්තියේ වස්තුවක් අවශ්ය නොවීමයි. ධාවන වේලාවේදී ඔබගේ යෙදුම නිර්මාණය කරන වස්තු ගණන අඩු කිරීමට මෙය ඔබට උපකාරී වේ.
OuterClass.Inner2 inner = outer.new Inner2();
?
static inner
පදවල පරස්පරයකි.
ජාවා අභ්යන්තර පන්තිය සහ ස්ථිතික කැදැලි පන්තිය අතර ප්රධාන වෙනස්කම් හා සමානකම් මෙන්න.
එය උපකාරී වේ යැයි සිතමු!
පංතිය වටකර ගැනීමේ උදාහරණය සමඟ සම්බන්ධ වී ඇති බැවින් එය ක්ෂණිකව තහවුරු කිරීම සඳහා පළමුව බාහිර පන්තියේ උදාහරණයක් අවශ්ය වේ ( නව මූල පදයක් සටහන් කරන්න ):
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
නොහැකි ඕනෑම අර්ථ ස්ථිතික සාමාජිකයන් ම
බාහිර පන්තියේ නිදර්ශන ක්රම හෝ ක්ෂේත්ර වෙත ප්රවේශ විය නොහැක
පංතිය කොටු කිරීමේ කිසිදු අවස්ථාවක් සමඟ සම්බන්ධ නොවේ. එබැවින් එය ක්ෂණිකව දැක්වීමට:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
ඔරකල් ප්රලේඛනයට අනුව හේතු කිහිපයක් තිබේ ( සම්පූර්ණ ලියකියවිලි ):
එය එක් ස්ථානයක පමණක් භාවිතා වන පන්ති තාර්කිකව කාණ්ඩගත කිරීමේ ක්රමයකි: පන්තියක් වෙනත් පන්තියකට පමණක් ප්රයෝජනවත් නම්, එය එම පන්තියට ඇතුළත් කර දෙක එකට තබා ගැනීම තර්කානුකූල ය. එවැනි "උපකාරක පන්ති" කැදැලි කිරීම ඔවුන්ගේ පැකේජය වඩාත් විධිමත් කරයි.
එය සංසරණය වැඩි කරයි: A සහ B යන ඉහළ මට්ටමේ පන්ති දෙකක් සලකා බලන්න, එහිදී B හි A සාමාජිකයින්ට ප්රවේශය අවශ්ය වන අතර එය වෙනත් ආකාරයකින් පුද්ගලික යැයි ප්රකාශයට පත් කෙරේ. A පන්තිය තුළ B පන්තිය සැඟවීමෙන්, A හි සාමාජිකයන් පුද්ගලික ලෙස ප්රකාශ කළ හැකි අතර B ඔවුන්ට ප්රවේශ විය හැකිය. ඊට අමතරව, B බාහිර ලෝකයෙන් සැඟවිය හැක.
එය වඩාත් කියවිය හැකි සහ නඩත්තු කළ හැකි කේතයකට මඟ පෑදිය හැකිය: ඉහළ මට්ටමේ පන්ති තුළ කුඩා පන්ති කැදැල්ල කිරීම කේතය එය භාවිතා කරන ස්ථානයට සමීප කරයි.
මම හිතන්නේ, සාමාන්යයෙන් අනුගමනය කරන සම්මුතිය මෙයයි:
කෙසේ වෙතත්, තවත් කිහිපයක් මතක තබා ගත යුතු කරුණු නම්:
ස්ථිතික කැදැලි පංතියකදී එහි පිටත [මව්] පන්තියේ පෞද්ගලික ස්ථිතික ක්ෂේත්ර / ක්රම පිළිබඳව ස්ථිතික සඳහනක් කළ හැකි අතර අනෙක් අතට ඉහළ මට්ටමේ පන්ති සහ ස්ථිතික කැදැලි පන්තිය අර්ථාන්විතව සමාන වේ.
අභ්යන්තර පංතිවලට පිටත [මව්] පන්තියේ සංවෘත උදාහරණයේ විචල්යයන් වෙත ප්රවේශය ඇත. කෙසේ වෙතත්, සෑම අභ්යන්තර පංතියකටම සංවෘත අවස්ථා නොමැත, නිදසුනක් ලෙස ස්ථිතික සන්දර්භය තුළ අභ්යන්තර පංති, ස්ථිතික ආරම්භක බ්ලොක් එකක භාවිතා කරන නිර්නාමික පන්තියක් වැනි නොවේ.
පෙරනිමියෙන් නිර්නාමික පංතිය මව් පන්තිය දීර් or කරයි හෝ මව් අතුරු මුහුණත ක්රියාත්මක කරයි. වෙනත් පංතියක් දීර් extend කිරීමට හෝ තවත් අතුරු මුහුණත් ක්රියාත්මක කිරීමට තවත් වගන්තියක් නොමැත. නිසා,
new YourClass(){};
මාධ්යයන් class [Anonymous] extends YourClass {}
new YourInterface(){};
මාධ්යයන් class [Anonymous] implements YourInterface {}
විවෘතව පවතින විශාල ප්රශ්නය කුමන එකක් භාවිතා කළ යුතුද සහ කවදාද? හොඳයි, එය බොහෝ දුරට රඳා පවතින්නේ ඔබ කටයුතු කරන්නේ කුමන තත්වයක් මතද යන්න පිළිබඳව වන නමුත් rjrudolph විසින් දෙන ලද පිළිතුර කියවීමෙන් ඔබට යම් තීරණයක් ගැනීමට උපකාරී වේ.
කැදැලි පන්තිය: පන්තිය ඇතුළත පන්තිය
වර්ග:
වෙනස:
ස්ථිතික නොවන කැදැලි පන්තිය [අභ්යන්තර පන්තිය]
අභ්යන්තර පංතියේ ස්ථිතික නොවන කැදැලි පන්තියේ වස්තුව බාහිර පන්තියේ වස්තුව තුළ පවතී. එබැවින් බාහිර පන්තියේ දත්ත සාමාජිකයාට අභ්යන්තර පන්තියට ප්රවේශ විය හැකිය. එබැවින් අභ්යන්තර පංතියේ වස්තුවක් නිර්මාණය කිරීමට නම් අප පළමුව බාහිර පන්තියේ වස්තුවක් නිර්මාණය කළ යුතුය.
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
ස්ථිතික කැදැලි පන්තිය
අභ්යන්තර පන්තියේ ස්ථිතික කැදැලි පන්තියේ වස්තුවට බාහිර පන්තියේ වස්තුවක් අවශ්ය නොවේ, මන්ද “ස්ථිතික” යන වචනයෙන් ඇඟවෙන්නේ වස්තුවක් නිර්මාණය කිරීමේ අවශ්යතාවයක් නොමැති බවයි.
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
ඔබට x වෙත පිවිසීමට අවශ්ය නම් පහත සඳහන් ක්රමය ලියන්න
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
බාහිර පංතියේ නිදසුනක් නිර්මාණය කරන විට අභ්යන්තර පන්තියේ උදාහරණය නිර්මාණය වේ. එබැවින් අභ්යන්තර පංතියේ සාමාජිකයින්ට සහ ක්රමවේදයන්ට බාහිර පංතියේ සාමාජිකයින්ට සහ නිදසුන් (වස්තුවට) ප්රවේශ විය හැකිය. බාහිර පංතියේ නිදසුන විෂය පථයෙන් බැහැර වූ විට, අභ්යන්තර පංති අවස්ථා ද අහෝසි වේ.
ස්ථිතික කැදැලි පන්තියට ස්ථිර උදාහරණයක් නොමැත. එය පළමු වරට භාවිතා කරන විට එය පටවනු ලැබේ (ස්ථිතික ක්රම මෙන්). එය සම්පුර්ණයෙන්ම ස්වාධීන ආයතනයකි, එහි ක්රම සහ විචල්යයන්ට බාහිර පන්තියේ අවස්ථාවන්ට ප්රවේශයක් නොමැත.
ස්ථිතික කැදැලි පංති පිටත වස්තුව සමඟ සම්බන්ධ නොවේ, ඒවා වේගවත් වන අතර ඒවා ගොඩවල් / සිරස් මතකය නොගනී, මන්ද එවැනි පංතියේ නිදසුනක් නිර්මාණය කිරීම අවශ්ය නොවන බැවිනි. එබැවින් මාපට ඇඟිල්ලේ රීතිය වන්නේ හැකි තරම් සීමිත විෂය පථයක් සහිත (පුද්ගලික> = පන්තිය> = ආරක්ෂිත> = පොදු) ස්ථිතික කැදැලි පන්තිය නිර්වචනය කිරීමට උත්සාහ කිරීම, පසුව එය අභ්යන්තර පන්තියට පරිවර්තනය කිරීම (“ස්ථිතික” හඳුනාගැනුම ඉවත් කිරීමෙන්) සහ ලිහිල් කිරීම විෂය පථය, එය සැබවින්ම අවශ්ය නම්.
ඇතැම් අවස්ථාවන්හිදී ප්රයෝජනවත් විය හැකි කූඩු ස්ථිතික පංති භාවිතය පිළිබඳ සියුම් බවක් ඇත.
පංතිය එහි ඉදිකිරීම්කරු හරහා ක්ෂණිකව ආරම්භ වීමට පෙර ස්ථිතික ගුණාංග ක්ෂණිකව ලබා ගත හැකි වුවද, කූඩුවල ස්ථිතික පංතිවල ස්ථිතික ගුණාංග පන්තියේ ඉදිකිරීම්කරුට ආයාචනා කිරීමෙන් පසුව හෝ අවම වශයෙන් ගුණාංග මුලින් සඳහන් කිරීමෙන් පසුව වුවද ක්ෂණිකව නොපෙනේ. ඒවා 'අවසාන' ලෙස සලකුණු කර ඇත.
මෙම උදාහරණය සලකා බලන්න:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
'කැදැල්ල' සහ 'අභ්යන්තර අයිටම්' යන දෙකම 'ස්ථිතික අවසාන' ලෙස ප්රකාශයට පත් කළද. nested.innerItem සැකසුම පන්තිය ක්ෂණිකව අවසන් වන තුරු (හෝ අවම වශයෙන් කැදැලි ස්ථිතික අයිතමය පළමු වරට සඳහන් කිරීමෙන් පසුව නොවේ), මා සඳහන් කරන රේඛා අදහස් දැක්වීමෙන් හා නොගැලපීමෙන් ඔබට දැක ගත හැකිය. ඉහත. 'OuterItem' සඳහා ද එය සත්ය නොවේ.
අවම වශයෙන් මෙය ජාවා 6.0 හි මා දකින දෙයයි.
යෙදුම් එකිනෙකට වෙනස් ලෙස භාවිතා කරයි. ඔබට ඒ පිළිබඳව සැබවින්ම විචක්ෂණශීලී වීමට අවශ්ය නම්, ස්ථිතික අභ්යන්තර පංතියක් වෙත යොමු කිරීම සඳහා ඔබට “කැදැලි පන්තිය” යන්න අර්ථ දැක්විය හැකිය . කේතයෙන්, ඔබට මේ වගේ දෙයක් තිබිය හැකිය:
public class Outer {
public class Inner {}
public static class Nested {}
}
එය සැබවින්ම පුළුල් ලෙස පිළිගත් අර්ථ දැක්වීමක් නොවේ.
නිදසුනක් නිර්මාණය කිරීමේදී, ස්ථිතික නොවන අභ්යන්තර පංතියේ නිදසුන නිර්මාණය කරනු ලබන්නේ එය නිර්වචනය කර ඇති බාහිර පන්තියේ වස්තුව යොමු කිරීමෙනි. මෙයින් අදහස් කරන්නේ එයට ඇතුළත් වීමේ නිදසුනක් ඇති බවයි. නමුත් ස්ථිතික අභ්යන්තර පංතියේ නිදසුන නිර්මාණය වී ඇත්තේ පිටත පන්තියේ සඳහනක් සමඟ මිස බාහිර පන්තියේ වස්තුවක් සමඟ නොවේ. මෙයින් අදහස් කරන්නේ එයට නිදසුනක් ඇතුළත් නොවන බවයි.
උදාහරණයක් වශයෙන්:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
මෙහි එකතු කිරීමට බොහෝ දේ ඇතැයි මම නොසිතමි, බොහෝ පිළිතුරු ස්ථිතික කැදැලි පන්තිය සහ අභ්යන්තර පන්ති අතර ඇති වෙනස්කම් මනාව පැහැදිලි කරයි. කෙසේ වෙතත්, අභ්යන්තර පංති එදිරිව කැදැලි පන්ති භාවිතා කරන විට පහත සඳහන් කරුණ සලකා බලන්න. සඳහන් ලෙස පිළිතුරු කිහිපයක් ඇතුළත පන්ති ඔවුන් කරන අදහස් තොරව හා ඔවුන්ගේ කවරෙ පන්තියේ උදාහරණයක් instantiated කළ නොහැකි ඇලී සිටින්න ඇති පහිටුම් දක්වනය මෙම GC නිසා යන කරුණ මතක පිරී ඉතිරී හෝ අඩුක්කුව පිටාර ගලා හැර ඇති විය හැකි ඔවුන්ගේ කවරෙ පන්තියේ උදාහරණයක් කිරීමට තව දුරටත් භාවිතා නොකලත්, කුණු කසළ එකතු කිරීමට නොහැකි වනු ඇත. මෙය පැහැදිලි කිරීම සඳහා පහත කේතය පරීක්ෂා කරන්න:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
// inner = null;
වැඩසටහන පිළිබඳ අදහස ඔබ ඉවත් කළහොත් වැඩසටහන " මම විනාශ වී ඇත " යනුවෙන් ප්රකාශ කරනු ඇත, නමුත් මෙය අදහස් දැක්වීම දිගටම කරගෙන යන්නේ නැත.
හේතුව, සුදු අභ්යන්තර නිදසුන තවමත් යොමු කර ඇති නිසා GC හට එය එකතු කළ නොහැකි අතර එය බාහිර උදාහරණය යොමු කර ඇති නිසා (එය යොමු කර ඇති නිසා) එය එකතු නොකෙරේ. ඔබේ ව්යාපෘතියේ මෙම වස්තූන් ප්රමාණවත් වීම සහ මතක ශක්තිය නැති විය හැකිය.
ස්ථිතික අභ්යන්තර පංති හා සසඳන විට අභ්යන්තර පංති නිදසුනකට ලක්ෂ්යයක් නොපවතින බැවින් එය උදාහරණ හා සම්බන්ධ නොවන නමුත් පන්ති සම්බන්ධ වේ. ඔබ අභ්යන්තර පංතිය ස්ථිතික කර ක්ෂණිකව කළහොත් ඉහත වැඩසටහනට " මම විනාශ වී ඇත! "Outer.Inner i = new Outer.Inner();
නෙස්ටඩ් පංතිය යනු ඉතා සාමාන්ය යෙදුමකි: ඉහළ මට්ටමේ නොමැති සෑම පන්තියක්ම කැදැලි පන්තියකි. අභ්යන්තර පංතිය යනු ස්ථිතික නොවන කැදැලි පන්තියකි. ජෝශප් ඩාර්සි නෙස්ටඩ්, අභ්යන්තර, සාමාජික සහ ඉහළ මට්ටමේ පන්ති ගැන ඉතා හොඳ පැහැදිලි කිරීමක් ලිවීය .
ම්ම්ම් ... අභ්යන්තර පංතියක් යනු කැදැලි පන්තියකි ... ඔබ අදහස් කරන්නේ නිර්නාමික පංතිය සහ අභ්යන්තර පන්තියද?
සංස්කරණය කරන්න: ඔබ සැබවින්ම අදහස් කළේ අභ්යන්තර එදිරිව නිර්නාමික නම් ... අභ්යන්තර පංතියක් යනු පංතියක් තුළ අර්ථ දක්වා ඇති පන්තියක් පමණි:
public class A {
public class B {
}
}
නිර්නාමික පංතියක් යනු නිර්නාමිකව අර්ථ දක්වා ඇති පන්තියේ දිගුවකි, එබැවින් සත්ය “පන්තියක්” අර්ථ දක්වා නැත.
public class A {
}
A anon = new A() { /* you could change behavior of A here */ };
වැඩිදුර සංස්කරණය කරන්න:
විකිපීඩියාව කියා සිටින්නේ ජාවා හි වෙනසක් ඇති බවයි, නමුත් මම වසර 8 ක් තිස්සේ ජාවා සමඟ වැඩ කර ඇති අතර, එවැනි වෙනසක් මා අසා ඇති පළමු අවස්ථාව මෙයයි ... හිමිකම් ඉල්ලීම උපස්ථ කිරීම සඳහා එහි කිසිදු සඳහනක් නොමැති බව සඳහන් නොකල යුතුය ... පහළ රේඛාව, අභ්යන්තර පංතිය යනු පන්තියක් තුළ අර්ථ දක්වා ඇති පන්තියකි (ස්ථිතික හෝ නැත), සහ කූඩුව යනු එකම දෙය අදහස් කරන තවත් යෙදුමකි.
ස්ථිතික හා ස්ථිතික නොවන කැදැලි පන්තිය අතර සියුම් වෙනසක් ඇත ... මූලික වශයෙන් ස්ථිතික නොවන අභ්යන්තර පංතිවලට නිදර්ශන ක්ෂේත්ර හා සංවෘත පන්තියේ ක්රමවේදයන් සඳහා ව්යංග ප්රවේශයක් ඇත (එබැවින් ඒවා ස්ථිතික සන්දර්භයක් තුළ ගොඩනගා ගත නොහැක, එය සම්පාදකයක් වනු ඇත දෝෂය). අනෙක් අතට, ස්ථිතික කැදැලි පංතිවලට නිදර්ශන ක්ෂේත්ර හා ක්රමවේදයන් සඳහා ව්යංග ප්රවේශයක් නොමැති අතර ස්ථිතික සන්දර්භයක් තුළ ගොඩනගා ගත හැකිය.
ජාවා සහ / හෝ නෙස්ටඩ් පංති සඳහා නවකයකු වන ඉගෙනුම් කරුවන් ඉලක්ක කිරීම
කැදැලි පන්ති විය හැකිය:
1. ස්ථිතික කැදැලි පන්ති.
2. ස්ථිතික නොවන කැදැලි පන්ති. ( අභ්යන්තර පන්ති ලෙසද හැඳින්වේ ) => කරුණාකර මෙය මතක තබා ගන්න
1. අභ්යන්තර පන්ති
උදාහරණය:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
අභ්යන්තර පන්ති යනු කැදැලි පන්තිවල උප කුලක වේ:
අභ්යන්තර පන්තියේ විශේෂත්වය:
2. ස්ථිතික කැදැලි පන්ති:
උදාහරණය:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
1 වන අවස්ථාව: සංවෘත නොවන පන්තියකින් ස්ථිතික කැදැලි පන්තියක් ස්ථාපනය කිරීම
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
2 වන අවස්ථාව: සංවෘත පන්තියකින් ස්ථිතික කැදැලි පන්තියක් ස්ථාපනය කිරීම
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
ස්ථිතික පන්තිවල විශේෂත්වය:
නිගමනය:
ප්රශ්නය: ජාවාහි අභ්යන්තර පන්තියක් සහ ස්ථිතික කැදැලි පන්තියක් අතර ඇති ප්රධාන වෙනස කුමක්ද?
පිළිතුර: ඉහත සඳහන් කළ එක් එක් පන්තියේ විශේෂතා හරහා යන්න.
අභ්යන්තර පන්තිය සහ කැදැලි ස්ථිතික පන්තියජාවාහි යන දෙකම වෙනත් පන්තියක් තුළ ප්රකාශයට පත් කරන ලද පන්ති වන අතර එය ජාවාහි ඉහළ මට්ටමේ පන්තිය ලෙස හැඳින්වේ. ජාවා පාරිභාෂිතයේ දී, ඔබ කැදැලි පන්තියේ ස්ථිතික යැයි ප්රකාශ කරන්නේ නම්, එය ජාවාහි කැදැලි ස්ථිතික පන්තිය ලෙස ද, ස්ථිතික නොවන කැදැලි පන්තිය හුදෙක් අභ්යන්තර පන්තිය ලෙස ද හැඳින්වේ.
ජාවාහි අභ්යන්තර පන්තිය යනු කුමක්ද?
ඉහළ පංතියක් නොවන හෝ වෙනත් පන්තියක් තුළ ප්රකාශයට පත් කරන ඕනෑම පන්තියක් කැදැලි පන්තිය ලෙස හැඳින්වෙන අතර එම කැදැලි පන්ති අතරින් ස්ථිතික නොවන බව ප්රකාශ කරන පන්තිය ජාවාහි අභ්යන්තර පන්තිය ලෙස හැඳින්වේ. ජාවාහි අභ්යන්තර පන්ති වර්ග තුනක් තිබේ:
1) දේශීය අභ්යන්තර පන්තිය - කේත වාරණයක් හෝ ක්රමයක් තුළ ප්රකාශයට පත් කෙරේ.
2) නිර්නාමික අභ්යන්තර පංතිය - යොමු දැක්වීමට නමක් නොමැති පන්තියක් වන අතර එය නිර්මාණය වූ ස්ථානයේදීම ආරම්භ වේ.
3) සාමාජික අභ්යන්තර පන්තිය - බාහිර පන්තියේ ස්ථිතික නොවන සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කෙරේ.
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
ජාවා හි කැදැලි ස්ථිතික පන්තිය යනු කුමක්ද?
නෙස්ටඩ් ස්ථිතික පංතිය යනු පංතියක් තුළ සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කර ස්ථිතික බවට පත් කරන තවත් පන්තියකි. කැදැලි ස්ථිතික පංතිය බාහිර පන්තියේ සාමාජිකයෙකු ලෙස ප්රකාශයට පත් කර ඇති අතර වෙනත් ඕනෑම සාමාජිකයෙකු මෙන් පුද්ගලික, පොදු හෝ ආරක්ෂා කළ හැකිය. අභ්යන්තර පංතියට වඩා කැදැලි ස්ථිතික පංතියේ එක් ප්රධාන වාසියක් වන්නේ කූඩුවල ස්ථිතික පංතියේ නිදසුන පිටත පන්තියේ කිසිදු සංවෘත අවස්ථාවකට සම්බන්ධ නොවීමයි. ජාවා හි කූඩු ස්ථිතික පංතියේ නිදසුනක් නිර්මාණය කිරීම සඳහා ඔබට පිටත පන්තියේ කිසිදු අවස්ථාවක් අවශ්ය නොවේ .
1) එයට පුද්ගලික ඇතුළුව බාහිර පන්තියේ ස්ථිතික දත්ත සාමාජිකයින්ට ප්රවේශ විය හැකිය .
2) ස්ථිතික කැදැලි පන්තියට ස්ථිතික නොවන (උදාහරණ) දත්ත සාමාජිකයෙකුට හෝ ක්රමයකට ප්රවේශ විය නොහැක .
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Ref: උදාහරණ සමඟ ජාවාහි අභ්යන්තර පන්තිය සහ කැදැලි ස්ථිතික පන්තිය
මම හිතන්නේ මෙහි සිටින අය පෝස්ටරයට අවධානය යොමු කළ යුතුයි: ස්ථිතික නෙස්ට් පන්තිය පළමු අභ්යන්තර පන්තිය පමණයි. උදාහරණයක් වශයෙන්:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
එබැවින්, සාරාංශගත කරන්න, ස්ථිතික පන්තිය එහි අඩංගු වන පන්තිය මත රඳා නොපවතී. එබැවින් ඔවුන්ට සාමාන්ය පන්තියේ සිටිය නොහැක. (සාමාන්ය පන්තියට උදාහරණයක් අවශ්ය නිසා).
අපි පන්තියක් තුළ ස්ථිතික සාමාජික පන්තිය ප්රකාශ කරන විට එය ඉහළ මට්ටමේ කැදැලි පන්තියක් හෝ ස්ථිතික කැදැලි පන්තියක් ලෙස හැඳින්වේ. එය පහත පරිදි නිරූපණය කළ හැකිය:
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
අපි පන්තියක් තුළ ස්ථිතික නොවන සාමාජික පංතිය ප්රකාශයට පත් කරන විට එය අභ්යන්තර පන්තිය ලෙස හැඳින්වේ. අභ්යන්තර පන්තිය පහත පරිදි නිරූපණය කළ හැකිය:
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
පහත දැක්වෙන්නේ static nested class
සහ inner class
:
පිටත ක්ලාස්.ජාවා
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
පිටත ක්ලාස් ටෙස්ට්:
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
යෙදුම් සැලසුම අනුව කැදැලි පන්තියක් සහ ස්ථිතික කැදැලි පන්තියක් අතර වෙනස ඉහත කිසිදු පිළිතුරක් ඔබට සැබෑ උදාහරණයක් සපයන්නේ නැතැයි මම සිතමි. ස්ථිතික කැදැලි පන්තිය සහ අභ්යන්තර පන්තිය අතර ඇති ප්රධාන වෙනස වන්නේ පිටත පන්තියේ නිදර්ශන ක්ෂේත්රයට ප්රවේශ වීමේ හැකියාවයි.
පහත උදාහරණ දෙක දෙස බලමු.
ස්ථිතික කැදැල්ල පන්තිය: ස්ථිතික කැදැලි පන්ති භාවිතා කිරීම සඳහා හොඳ උදාහරණයක් වන්නේ තනන්නාගේ රටාවයි ( https://dzone.com/articles/design-patterns-the-builder-pattern ).
BankAccount සඳහා අපි ස්ථිතික කැදැලි පන්තියක් භාවිතා කරමු
පිටත පන්තියට පෙර ස්ථිතික කූඩු පන්තියේ නිදසුනක් නිර්මාණය කළ හැකිය.
තනන්නාගේ රටාව තුළ, තනන්නා යනු බැංකු ගිණුම නිර්මාණය කිරීම සඳහා භාවිතා කරන උපකාරක පන්තියකි.
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
අභ්යන්තර පංතිය: අභ්යන්තර පංතිවල පොදු භාවිතයක් වන්නේ සිදුවීම් හසුරුවන්නෙකු නිර්වචනය කිරීමයි. https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
MyClass සඳහා, අපි අභ්යන්තර පන්තිය භාවිතා කරමු.
අභ්යන්තර පන්තියේ MyAdapter පිටත පන්තියේ සාමාජිකයාට ප්රවේශ විය යුතුය.
උදාහරණයේ දී, MyAdapter සම්බන්ධ වන්නේ MyClass සමඟ පමණි. වෙනත් කිසිදු පංතියක් MyAdapter හා සම්බන්ධ නොවේ. එබැවින් නාම සම්මුතියක් භාවිතා නොකර ඒවා එකට සංවිධානය කිරීම වඩා හොඳය
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
පළමුවෙන්ම ස්ථිතික පංතිය නමින් එවැනි පංතියක් නොමැත. අභ්යන්තර පංතිය සමඟ ස්ථිතික විකරණකාරක භාවිතය (නෙස්ටඩ් පංතිය ලෙස හැඳින්වේ) එය පිටත පන්තියේ ස්ථිතික සාමාජිකයෙකු වන අතර එයින් අදහස් කරන්නේ අපට වෙනත් ස්ථිතික සාමාජිකයන් හා සමානව ප්රවේශ විය හැකි බවයි. පිටත පන්තියේ උදාහරණය. (මුලින් ස්ථිතිකයේ වාසිය එයයි.)
නෙස්ටඩ් පංතිය සහ සාමාන්ය අභ්යන්තර පන්තිය භාවිතා කිරීම අතර වෙනස:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
පළමුව අපට පිටත පන්තිය ක්ෂණිකව ක්රියාත්මක කළ හැකි අතර පසුව අපට අභ්යන්තරයට පිවිසිය හැකිය.
නමුත් පන්තිය කැදැල්ල නම් සින්ටැක්ස් යනු:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
ස්ථිතික මූල පදය සාමාන්ය ලෙස ක්රියාත්මක කිරීම සඳහා ස්ථිතික සින්ටැක්ස් භාවිතා කරයි.
ජාවා ක්රමලේඛන භාෂාව ඔබට වෙනත් පන්තියක් තුළ පන්තියක් අර්ථ දැක්වීමට ඉඩ දෙයි. එවැනි පංතියක් කැදැලි පන්තියක් ලෙස හැඳින්වෙන අතර එය මෙහි දැක්වේ:
class OuterClass {
...
class NestedClass {
...
}
}
කැදැලි පන්ති කොටස් දෙකකට බෙදා ඇත: ස්ථිතික හා ස්ථිතික නොවන. ස්ථිතික ලෙස ප්රකාශයට පත් කරන ලද කූඩු පන්ති ස්ථිතික කැදැලි පන්ති ලෙස හැඳින්වේ. ස්ථිතික නොවන කැදැලි පන්ති අභ්යන්තර පන්ති ලෙස හැඳින්වේ. අප මතක තබා ගත යුතු එක් කරුණක් නම්, ස්ථිතික නොවන කැදැලි පන්තිවලට (අභ්යන්තර පංති) පුද්ගලික යැයි ප්රකාශයට පත් කළත්, සංවෘත පන්තියේ අනෙකුත් සාමාජිකයින්ට ප්රවේශ විය හැකිය. ස්ථිතික කැදැලි පංතිවලට ප්රවේශ විය හැක්කේ සංවෘත පන්තියේ අනෙක් සාමාජිකයින්ට ස්ථිතික නම් පමණි. බාහිර පන්තියේ ස්ථිතික නොවන සාමාජිකයින්ට එයට ප්රවේශ විය නොහැක. පන්ති ක්රම සහ විචල්යයන් මෙන්ම, ස්ථිතික කැදැලි පන්තියක් එහි බාහිර පන්තිය සමඟ සම්බන්ධ වේ. උදාහරණයක් ලෙස, ස්ථිතික කැදැලි පන්තිය සඳහා වස්තුවක් නිර්මාණය කිරීම සඳහා, මෙම වාක්ය ඛණ්ඩය භාවිතා කරන්න:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
අභ්යන්තර පංතියක් ස්ථාපනය කිරීම සඳහා, ඔබ පළමුව බාහිර පන්තිය ක්ෂණිකව ක්රියාත්මක කළ යුතුය. ඉන්පසු, මෙම වාක්ය ඛණ්ඩය සමඟ පිටත වස්තුව තුළ අභ්යන්තර වස්තුව සාදන්න:
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
ඇයි අපි කැදැලි පන්ති භාවිතා කරන්නේ
මූලාශ්රය: ජාවා ut නිබන්ධන - කැදැලි පන්ති
වෙනස නම්, කූඩුවල පන්ති ප්රකාශයක් ස්ථිතික වන අතර එය සංවෘත පන්තියෙන් පිටත ක්ෂණිකව දැක්විය හැකිය.
අභ්යන්තර පන්තියක් ලෙසද හැඳින්වෙන ස්ථිතික නොවන කැදැලි පංති ප්රකාශයක් ඔබ සතුව ඇති විට , ජාවා ඔබට එය ක්ෂණිකව ක්ෂණික පන්තිය හරහා හැරෙන්නට ඉඩ නොදේ. අභ්යන්තර පන්තියෙන් සාදන ලද වස්තුව බාහිර පන්තියෙන් නිර්මාණය කරන ලද වස්තුව සමඟ සම්බන්ධ වී ඇති බැවින් අභ්යන්තර පන්තියට පිටත ක්ෂේත්ර යොමු කළ හැකිය.
නමුත් එය ස්ථිතික නම්, සබැඳිය නොපවතී, පිටත ක්ෂේත්ර වෙත ප්රවේශ විය නොහැක (වෙනත් වස්තුවක් වැනි සාමාන්ය සඳහනක් හැර) ඔබට එම නිසා කූඩු පන්තිය තනිවම කළ හැකිය.
ජාවා කේතයේ සිදුවිය හැකි විවිධ නිවැරදි හා වැරදි අවස්ථා මම නිදර්ශනය කර ඇත්තෙමි.
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}
item 22 : Favor static member classes over non static