1. Lahat ng klase ay nagmamanaObject

Lahat ng mga klase sa Java ay tahasang nagmamana ng Objectklase.

Susuriin namin kung ano ang inheritance at kung paano ito gumagana sa Java sa Java Core quest. Sa ngayon, isasaalang-alang namin ang isang simpleng katotohanan na sumusunod dito:

Ang isang bagay ng anumang klase ay maaaring italaga sa isang Objectvariable. Halimbawa:

Code Tandaan
Object o = new Scanner(System.in);
Ang ovariable ay nag-iimbak ng isang sanggunian sa isang Scannerbagay
Object o = new String();
Ang ovariable ay nag-iimbak ng isang sanggunian sa isang Stringbagay
Object o = new Integer(15);
Ang ovariable ay nag-iimbak ng isang sanggunian sa isang Integerbagay
Object o = "Hello";
Ang ovariable ay nag-iimbak ng isang sanggunian sa isang Stringbagay

Dito nagtatapos ang mabuting balita. Hindi sinusubaybayan ng compiler ang orihinal na uri ng bagay na naka-save sa isang Objectvariable, kaya hindi ka makakatawag ng mga pamamaraan sa naka-save na bagay maliban sa mga pamamaraan ng Objectklase.

Kung kailangan mong tawagan ang mga pamamaraan na nauugnay sa orihinal na uri ng bagay, kailangan mo munang mag-save ng isang reference dito sa isang variable ng tamang uri, at pagkatapos ay tawagan ang mga pamamaraan sa variable na iyon:

Code Tandaan
Object o = new Scanner(System.in);
int x = o.nextInt();
Ang programa ay hindi mag-compile. ObjectWalang paraan ang klase nextInt().
Object o = new Scanner(System.in);

Scanner console = (Scanner) o;

int x = console.nextInt();
Ito ay gagana.

Dito nagse-save kami ng isang reference sa isang Scannerbagay sa isang Scannervariable gamit ang isang typecast operator .

Hindi ka maaaring pumunta lamang at magtalaga ng isang Objectvariable sa isang variable ng Scanner, kahit na ang Objectvariable ay nag-iimbak ng isang reference ng isang Scannerbagay. Ngunit magagawa mo ito kung gagamitin mo ang typecast operator , na alam mo na. Ito ang pangkalahatang hitsura nito:

Type name1 = (Type) name2;

Nasaan name1ang pangalan ng Typevariable, at name2ang pangalan ng Objectvariable na nag-iimbak ng reference sa isang Typeobject.

Typecasting

Kung hindi magkatugma ang uri ng variable at uri ng object, ClassCastExceptionitatapon ang isang. Halimbawa:

Code Tandaan
Object o = new Integer(5);
String s = (String) o;
Isang error ang magaganap sa runtime:
a ClassCastExceptionay itatapon dito

Mayroong isang paraan upang maiwasan ang error na ito sa Java: ginagawa namin ito sa pamamagitan ng pagsuri sa uri ng bagay na nakaimbak sa isang variable :

name instanceof Type

Sinusuri ng instanceofoperator kung ang namevariable ay isang Typebagay.

Bilang halimbawa, hanapin natin ang isang string sa hanay ng magkakaibang mga bagay:

Code Tandaan
Object[] objects = {10, "Hello", 3.14};

for (int i = 0; i < objects.length; i++)
{
   if (objects[i] instanceof String)
   {
      String s = (String) objects[i];
      System.out.println(s);
   }
}
Iko-convert ng Autoboxing ang mga halagang ito sa isang Integer, String, at Double, ayon sa pagkakabanggit.

I-loop ang hanay ng mga bagay

Kung ang bagay ay isang String

I-save ito sa isang Stringvariable
Ipakita ang variable sa screen.


2. Bakit lumitaw ang mga generics — mga koleksyon

Bumalik tayo sa mga koleksyon.

Sa sandaling nilikha ng mga developer ng Java ang ArrayListklase, nais nilang gawin itong unibersal, upang makapag-imbak ito ng anumang uri ng bagay. Kaya gumamit sila ng isang array ng Objects upang iimbak ang mga elemento.

Ang lakas ng diskarteng ito ay maaari kang magdagdag ng isang bagay ng anumang uri sa koleksyon.

Siyempre, may ilang mga kahinaan.

Kahinaan 1.

Palaging kinakailangan na magsulat ng operator ng uri ng conversion kapag kumukuha ng mga elemento mula sa isang koleksyon:

Code Tandaan
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 10);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Lumikha ng isang koleksyon upang mag-imbak ng mga sanggunian sa Objectmga bagay

Punan ang koleksyon ng mga numero 10, 20, ... 100;



Isama ang mga elemento ng koleksyon


Typecasting ay kinakailangan

Kahinaan 2.

Walang garantiya na ang isang koleksyon ay naglalaman ng isang partikular na uri ng elemento

Code Tandaan
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 2.5);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Lumikha ng isang koleksyon upang mag-imbak ng mga sanggunian sa Objectmga bagay

Pinupuno namin ang koleksyon ng mga numero na kinakatawan bilang Doublemga bagay:
0.0, 2.5, 5.0, ...


Isama ang mga elemento ng koleksyon


Magkakaroon ng error: a Doublehindi maaaring i-cast sa isangInteger

Maaaring ilagay ang data sa koleksyon kahit saan:

  • sa ibang paraan
  • sa ibang programa
  • mula sa isang file
  • sa network

Kahinaan 3.

Ang data sa koleksyon ay maaaring mabago nang hindi sinasadya.

Maaari mong ipasa ang isang koleksyon na puno ng iyong data sa ilang paraan. Ang paraang iyon, na isinulat ng ibang programmer, ay nagdaragdag ng data nito sa iyong koleksyon.

Ang pangalan ng koleksyon ay hindi malinaw na nagsasaad kung aling mga uri ng data ang maaaring maimbak dito. At kahit na bigyan mo ng malinaw na pangalan ang iyong variable, maaaring maipasa ang isang reference dito sa isang dosenang mga pamamaraan, at tiyak na walang malalaman ang mga pamamaraang iyon tungkol sa orihinal na pangalan ng variable.


3. Generics

Generics sa Java

Sa Java, ang lahat ng mga problemang ito ay inalis ng cool na bagay na ito na tinatawag na generics.

Sa Java, ang generics ay nangangahulugan ng kakayahang magdagdag ng mga parameter ng uri sa mga uri. Ang resulta ay isang kumplikadong uri ng composite. Ang pangkalahatang view ng naturang composite type ay ito:

ClassName<TypeParameter>

Isa itong generic na klase. At maaari itong gamitin saanman karaniwan mong ginagamit ang mga klase.

Code Paglalarawan
ArrayList<Integer> list;
Paglikha ng mga variable
list = new ArrayList<Integer> ();
Paglikha ng mga bagay
ArrayList<Integer>[] array;
Paglikha ng mga array

Ang mga variable lamang Integerang maaaring maimbak sa naturang koleksyon:

Code Paglalarawan
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(2);
list.add("Hello");
ArrayListkoleksyon na may Integermga elemento
Ito ay pinapayagan
At ito ay gagana rin
Autoboxing

Ngunit ito ay hindi pinapayagan: compilation error

Matututuhan mo kung paano gumawa ng sarili mong mga klase na may mga uri ng parameter sa Java Collections quest. Sa ngayon, titingnan natin kung paano gamitin ang mga ito at kung paano gumagana ang mga ito.


4. Paano gumagana ang generics

Sa totoo lang, ang mga generic ay napaka-primitive.

Pinapalitan lang ng compiler ang mga generic na uri ng mga ordinaryong uri. Ngunit kapag ginamit ang mga pamamaraan ng generic na uri, nagdaragdag ang compiler ng typecast operator upang mag-cast ng mga parameter sa mga parameter ng uri:

Code Ano ang ginagawa ng compiler
ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList list = new ArrayList();
list.add(1);
list.add( (Integer) 1 );
int x = list.get(0);
int x = (Integer) list.get(0);
list.set(0, 10);
list.set(0, (Integer) 10);

Ipagpalagay na mayroon kaming isang paraan na nagsusuma ng mga numero sa isang koleksyon ng mga integer:

Code Ano ang ginagawa ng compiler
public int sum(ArrayList<Integer> numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + numbers.get(i);

   return result;
}
public int sum(ArrayList numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + (Integer) numbers.get(i);

   return result;
}

Sa madaling salita, ang mga generic ay isang uri ng syntactic na asukal, tulad ng autoboxing, ngunit higit pa. Sa autoboxing, nagdaragdag ang compiler ng mga pamamaraan para sa pag-convert ng an intsa isang Integerat vice versa, at para sa mga generic ay nagdaragdag ito ng mga operator ng typecast.

Matapos i-compile ng compiler ang iyong mga generic na klase na may mga parameter ng uri, iko-convert lang ang mga ito sa mga ordinaryong klase at mga operator ng typecast. Nawala ang impormasyon tungkol sa mga uri ng argumento na ipinasa sa mga variable ng mga generic na uri. Ang epektong ito ay tinatawag ding type erasure .

Minsan ang mga programmer na nagsusulat ng mga generic na klase (mga klase na may mga parameter ng uri) ay talagang nangangailangan ng impormasyon tungkol sa mga uri na ipinasa bilang mga argumento. Sa Java Collections quest, matututunan mo kung paano haharapin ito at kung ano ang kasama nito.



5. Ilang katotohanan tungkol sa generics

Narito ang ilang mas kawili-wiling mga katotohanan tungkol sa generics.

Ang mga klase ay maaaring magkaroon ng ilang uri ng mga parameter. Mukhang ganito:

ClassName<TypeParameter1, TypeParameter2, TypeParameter3>

Sa totoo lang, hindi ito nakakagulat. Saanman ang compiler ay maaaring magdagdag ng isang operator upang i-cast sa isang uri, maaari itong magdagdag ng maramihang mga typecast operator.

Mga halimbawa:

Code Tandaan
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(7, "Hello");
map.put(-15, "Hello");
Ang putunang parameter ng pamamaraan ay isang Integer, at ang pangalawa ay aString

Ang mga generic na uri ay maaari ding gamitin bilang mga parameter . Mukhang ganito:

ClassName<TypeParameter<TypeParameterParameter>>

Ipagpalagay na gusto naming lumikha ng isang listahan na mag-iimbak ng mga listahan ng mga string. Sa kasong ito, makakakuha tayo ng ganito:

// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");

// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");

// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);

Ang mga generic na uri (mga uri na may mga parameter ng uri) ay maaari ding gamitin bilang mga uri ng array. Mukhang ganito:

ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];

Walang mahiwagang nangyayari dito: ipinapahiwatig lamang ng mga anggulong bracket ang pangalan ng uri:

Code Non-generic na katapat
ArrayList<String>[] list = new ArrayList<String>[10];
StringArrayList[] list = new StringArrayList[10];
ArrayList<Integer>[] list = new ArrayList<Integer>[10];
IntegerArrayList[] list = new IntegerArrayList[10];
ArrayList<Scanner>[] list = new ArrayList<Scanner>[10];
ScannerArrayList[] list = new ScannerArrayList[10];