Inleiding Informatica

January 8, 2018 | Author: Anonymous | Category: Engineering & Technology, Informatica, Java Programming
Share Embed Donate


Short Description

Download Inleiding Informatica...

Description

Hoofdstuk 4: Klassen definiëren

Inleiding Informatica

Prof. Dr. O. De Troyer

Klasse • Herinner: Gelijksoortige objecten met hetzelfde gedrag en gelijksoortige attributen worden gedefinieerd door een klasse • Toestand: attributen of instantie variabelen • Gedrag: methoden

– Prototype van een methode » Naam methode, beschrijving van de argumenten en beschrijving van de “return” waarde – Argumenten worden ook wel parameters genoemd

Inleiding Informatica

Prof. Dr. O. De Troyer

2

Klasse definitie class klasse-naam { instantie variabelen constructor definities methode definities } Voorbeeld

Class Lacher { ... } Inleiding Informatica

delimiter

Gebruik Lacher x ;

klasse-naam x Prof. Dr. O. De Troyer

3

Methode definitie public return-waarde methode-naam ( parameter-definities) { body van de methode } Voorbeeld

Return-waarde: geen

public void lachen ( ) { System.out.println( “haha”); System.out.println( “haha”); }

Parameterdefinities: geen

Methode-naam Body van de methode Inleiding Informatica

Prof. Dr. O. De Troyer

4

Methode aanroep • Veronderstel een referentie variabele x die verwijst naar een object van de klasse Lacher ... Lacher x ; ... x.lachen() ;

x

lachen() lachen()

Inleiding Informatica

Prof. Dr. O. De Troyer

Lacher object

5

Methode - uitvoering public void lachen ( ) { System.out.println( “haha”); System.out.println( “haha”); } lachen()

x

Lacher object

• Instructies in de body van de methode worden één voor één uitgevoerd

Inleiding Informatica

Prof. Dr. O. De Troyer

6

Constructor definitie • Zoals methode • Geen return-type • Naam is steeds naam van de klasse • Herinner: constructor maakt bij aanroep een nieuwe instantie van de klasse

Inleiding Informatica

Prof. Dr. O. De Troyer

7

Constructor definitie - voorbeeld Definitie van een constructor

Voorbeeld class Lacher { public Lacher ( ) { // deze constructor maakt alleen een nieuwe instantie // van de klasse Lachter, verder doet die niets } } Gebruik

x

Lacher x ; x = new Lacher(); Inleiding Informatica

Lacher object Prof. Dr. O. De Troyer

8

Voorbeeld Lacher class Lacher { public Lacher ( ) { } public void lachen ( ) { System.out.println( “haha”); System.out.println( “haha”); } } Gebruik

De constructor

Een methode

Lacher x ; x = new Lacher(); x.lachen() ;

Inleiding Informatica

Prof. Dr. O. De Troyer

9

Voorbeeld Lacher - meerdere instanties class Lacher { public Lacher ( ) { } public void lachen ( ) { System.out.println( “haha”); System.out.println( “haha”); } Gebruik }

Lacher x , y; x = new Lacher(); y = new Lacher(); x.lachen() ; y.lachen() ;

Inleiding Informatica

Prof. Dr. O. De Troyer

x

Lacher object y

Lacher object 10

Methode met argumenten • We willen het geluid van de lacher kunnen veranderen. – Via een argument bij de methode lachen x.lachen ( “hihi”) x.lachen (“hoho”)

type

– Methode definitie:

Naam van de parameter

public void lachen (String geluid )

Definitie van het argument, ook parameter genoemd Inleiding Informatica

Prof. Dr. O. De Troyer

11

Methode definitie - met parameters Voorbeeld public void lachen (String geluid ) { System.out.println( geluid ) ; System.out.println( geluid ) ; }

Inleiding Informatica

Gebruik van de parameter, zoals een variabele

Prof. Dr. O. De Troyer

12

Parameters • Een parameter is zoals een variabele, maar – bestaat maar zolang de methode uitgevoerd wordt – De waarde bij aanvang wordt gegeven bij de aanroep van de methode

Inleiding Informatica

Prof. Dr. O. De Troyer

13

Parameters - werking public void lachen (String geluid ) { System.out.println( geluid ) ; System.out.println( geluid ) ; }

Werking bij activatie x.lachen(“hihi”) ;

Inleiding Informatica

Prof. Dr. O. De Troyer

geluid

“hihi”

14

Parameters - werking (2) public void lachen (String geluid ) { System.out.println( geluid ) ; System.out.println( geluid ) ; }

Werking bij activatie x.lachen(“hihi”) ; x.lachen(“hoho”) ;

Inleiding Informatica

Prof. Dr. O. De Troyer

geluid

“hihi”

15

Parameters - werking public void lachen (String geluid ) { System.out.println( geluid ) ; System.out.println( geluid ) ; }

Werking bij activatie x.lachen(“hihi”) ; x.lachen(“hoho”) ;

Inleiding Informatica

Prof. Dr. O. De Troyer

geluid

“hoho”

16

Klasse definitie met overloading class Lacher { public Lacher ( ) { } public void lachen () { System.out.println( “haha”) ; } public void lachen (String geluid ) { System.out.println( geluid ) ; } } Inleiding Informatica

Prof. Dr. O. De Troyer

Methode naam is “overladen” Maar verschillende signatuur.

Gebruik Lacher x ; x = new Lacher ; x.lachen(); x.lachen(“hihi”) ; 17

Klasse definitie met instantie variabelen • Instantie variabelen dienen om toestand van een object te beschrijven • Zijn variabelen • Zijn toegankelijk vanuit al de methoden gedefinieerd in de klasse • Zijn enkel toegankelijk voor die methoden private type identifier

Inleiding Informatica

Prof. Dr. O. De Troyer

18

Voorbeeld instantie variabelen Voorbeeld: Lacher klasse die toelaat om het default lachgeluid bij het maken van een object vast te leggen. class Lacher {

Instantie variabele

private String defaultGeluid ; public Lacher (String geluid ) { …} public void lachen () { …} public void lachen (String geluid) { …} }

Inleiding Informatica

Prof. Dr. O. De Troyer

Gebruik Lacher x ; x = new Lacher( “hihi”);

x defaultGeluid

19

Gebruik van instantie variabelen class Lacher {

Instantie variabele

private String defaultGeluid ; public Lacher (String default ) { defaultGeluid = default ; } public void lachen () { System.out.println( defaultGeluid) ; } public void lachen (String geluid) { System.out.println( geluid) ; } x }

Gebruik van de instantie variabele

Gebruik Lacher x ; x = new Lacher(‘hihi”); x .lachen(); x .lachen(“haha”); defaultGeluid “hihi”

Inleiding Informatica

Prof. Dr. O. De Troyer

20

Meerdere instanties en instantie variabelen class Lacher { private String defaultGeluid ;

Gebruik

public Lacher (String default ) { defaultGeluid = default ; } public void lachen () { System.out.println( defaultGeluid) ; } public void lachen (String geluid) { System.out.println( geluid) ; } } x defaultGeluid “hihi” Inleiding Informatica

Prof. Dr. O. De Troyer

Lacher x, y ; x = new Lacher(‘hihi”); y = new Lacher(‘hoho”); x .lachen(); y .lachen();

y defaultGeluid “hoho” 21

Variabelen voor methoden • We wijzigen de klasse en houden in de instantie variabele enkel de klank bij, bv. “ha” of “hi”. Bij de methode lachen wordt het lachgeluid dan samengesteld door concatenatie. class Lacher { private String defaultKlank ; public Lacher (String klank ) { defaultKlank = klank ; } public void lachen () { String geluid; geluid = defaultKlank.concat(defaultKlank) ; System.out.println( geluid) ; } }

Inleiding Informatica

Prof. Dr. O. De Troyer

Variabele enkel voor de methode lachen() Is een lokale variabele

23

Lokale variabelen - werking public void lachen () { String geluid; geluid = defaultKlank.concat(defaultKlank) ; System.out.println( geluid) ; geluid }

Werking bij activatie Lacher x; x = new Lacher(‘hi”); x.lachen() ;

“hihi”

x defaultKlank “hi”

Inleiding Informatica

Prof. Dr. O. De Troyer

24

Meerdere methoden met variabelen class Lacher { Private String defaultKlank ; public Lacher (String klank ) { defaultKlank = klank ; } Variabele enkel voor public void lachen () { deze methode lachen() String defaultGeluid; defaultGeluid = defaultKlank.concat(defaultKlank) ; System.out.println( defaultGeluid) ; } public void lachen (String klank) { Variabele enkel voor de String geluid; methode lachten(String geluid = klank.concat(klank) ; klank) System.out.println( geluid) ; } } Inleiding Informatica

Prof. Dr. O. De Troyer

25

Een klasse gebruiken • Stap 1: maak bestand klasse-naam.java met klasse definitie • Stap 2: Compileer dit bestand -> resultaat bestand klasse-naam.class • Stap 3: klasse kan nu gebruikt worden Inleiding Informatica

Prof. Dr. O. De Troyer

26

Voorbeeld - definitie klasse • Lacher.java bestand import java.io.*; class Lacher {

//nodig omdat we een PrintStream object gebruiken

private String defaultKlank ; public Lacher (String klank ) { defaultKlank = klank ; } public void lachen () { String geluid; geluid = defaultKlank.concat(defaultKlank) ; System.out.println( geluid) ; } public void lachen (String klank) { String geluid; geluid = klank.concat(klank) ; System.out.println( geluid) ; } } Inleiding Informatica

Prof. Dr. O. De Troyer

27

Voorbeeld - gebruik klasse import java.io.*; class ProgrammaLachen { public static void main(String[ ] arg) { System.out.println(“Lekker lachen”); Lacher x, y ; x = new Lacher(“yuk”) ; y = new Lacher(“harr”); x.lachen(); x.lachen(“hee”); y.lachen(); } } Inleiding Informatica

Prof. Dr. O. De Troyer

28

Klassen ontwerpen Methode 1. Bepaal het gewenste gedrag methoden

2. Bepaal de interface van de methoden Prototype van de methoden

3. Schrijf een voorbeeld programma die de klasse gebruikt Check

4. Maak het skelet van de klasse 5. Schrijf de code voor de methoden (implementeer) Inleiding Informatica

Prof. Dr. O. De Troyer

29

Voorbeeld - klasse ontwerp • Ontwerp klasse voor het behandelen van tijdstippen : class Tijdstip

Inleiding Informatica

Prof. Dr. O. De Troyer

30

Tijdstip vb - Bepaal het gedrag • We willen het volgende gedrag – Een tijdstip een waarde (uren, min en sec) kunnen geven – Het uur van een tijdstip kunnen opvragen – De minuten van een tijdstip kunnen opvragen – De seconden van een tijdstip kunnen opvragen – Het uur van een tijdstip kunnen wijzigen – De minuten van een tijdstip kunnen wijzigen – De seconden van een tijdstip kunnen wijzigen – Het tijdstip kunnen afdrukken op het scherm

Inleiding Informatica

Prof. Dr. O. De Troyer

31

Tijdstip vb - Bepaal de interface – Class name: Tijdstip – Constructor: Tijdstip() • Vb: Tijdstip t1 = new Tijdstip(); public Tijdstip() – Tijdstip een waarde geven: Vb: t1.zet(23, 40, 15); public void zet( int u, int m, int s) – Het uur van een tijdstip kunnen opvragen: Vb: int u1 ; u1 = t1.geefUur(); public int geefUur( ) Inleiding Informatica

Prof. Dr. O. De Troyer

32

Tijdstip vb - Bepaal de interface (vervolg) – De minuten van een tijdstip kunnen opvragen: Vb: int m1 ; m1 = t1.geefMin(); public int geefMin( ) – De sec van een tijdstip kunnen opvragen: Vb: int s1 ; s1 = t1.geefSec(); public int geefSec( ) – Het uur van een tijdstip kunnen wijzigen: Vb: t1.wijzigUur(11); public void wijzigUur( int u) Inleiding Informatica

Prof. Dr. O. De Troyer

33

Tijdstip vb - Bepaal de interface (vervolg) – De minuten van een tijdstip kunnen wijzigen: Vb: t1.wijzigMin(44); public void wijzigMin( int m) – De seconden van een tijdstip kunnen wijzigen: Vb: t1.wijzigSec(20); public void wijzigSec( int s) – Het tijdstip kunnen afdrukken op het scherm: Vb: t1.drukaf(); public void drukaf( )

Inleiding Informatica

Prof. Dr. O. De Troyer

34

Tijdstip vb - Een vb-programma import java.io.*; class ProbeerTijdstip { public static void main(String[ ] arg) throws IOException { Tijdstip t1 = new Tijdstip (); Tijdstip t2 = new Tijdstip(); t1.zet(10, 15, 30) ; int u, m, s ; u = t1.geefUur (); m = t1.geefMin() ; s = t1.geefSec(); t2.zet(u +1, m, s) ; t1.wijzigMin(30) ; t1.drukaf(); t2.drukaf(); } } Inleiding Informatica

Prof. Dr. O. De Troyer

35

Tijdstip vb - Klasse skelet class Tijdstip { instantie variabelen indien nodig public Tijdstip() { statements } // geef waarde public void zet(int u, int m, int s) { statements } // geef uur; public int geefUur( ) { statements }

Inleiding Informatica

Prof. Dr. O. De Troyer

36

Tijdstip vb - Klasse skelet (vervolg) // geef min; public int geefMin( ) { statements } // geef sec; public int geefSec( ) { statements } // wijzig uur ; public void wijzigUur(int u) { statements } // wijzig min ; public void wijzigMin(int m) { statements } Inleiding Informatica

Prof. Dr. O. De Troyer

37

Tijdstip vb - Klasse skelet (vervolg) // wijzig sec ; public void wijzigSec(int s) { statements } // druk af op het scherm public void drukaf ( ) { statements } }

Inleiding Informatica

Prof. Dr. O. De Troyer

38

Tijdstip vb - Implementatie • Welke instantie variabelen nodig? – Bijhouden uur, minuten, seconden • 3 integer variabelen: uur, min en sec

int uur, min, sec ;

• De constructor Tijdstip() public Tijdstip() { }

Inleiding Informatica

Prof. Dr. O. De Troyer

39

Tijdstip vb - Implementatie (2) • Begin bij eender welke methode – Meestal de gemakkelijkste Bv. zet public void zet(int u, int m, int s) { uur = u ; min = m ; sec = s ; }

Inleiding Informatica

Prof. Dr. O. De Troyer

40

Tijdstip vb - Implementatie (3) • De methodes geefUur, geefMin en geefSec public int geefUur() { return uur ; } Speciale instructie: “return waarde” ; public int geefMin() { return min ; } public int geefSec() { return sec ; }

Inleiding Informatica

Prof. Dr. O. De Troyer

41

Tijdstip vb - Implementatie (4) • De methodes wijzigUur, wijzigMin en wijzigSec public void wijzigUur(int u) { uur = u ; } public void wijzigMin(int m) { min = m ; } public void wijzigSec(int s) { sec = s ; }

Inleiding Informatica

Prof. Dr. O. De Troyer

42

Tijdstip vb - Implementatie (5) • De methode drukaf public void drukaf() { String tijdstipAlsString ; // in het formaat uu:mm:ss tijdstipAlsString = uur + “:” + min + “:” + sec ; System.out.println( tijdstipAlsString); }

of nog korter

public void drukaf() { System.out.println(uur + “:” + min + “:” + sec ); }

Inleiding Informatica

Prof. Dr. O. De Troyer

43

Declaratie volgorde • De volgorde van variabelen en methoden binnen een klasse is niet van belang. • Java Conventie: – Constructors – Methoden – Instantie variabelen

Inleiding Informatica

Prof. Dr. O. De Troyer

44

Return statement • Uitvoering van een methode stopt indien:

1. return-statement wordt uitgevoerd 2. Einde ( } ) van methode bereikt wordt bij voidmethode

• Void-methode kan ook return hebben return; public void drukaf() { System.out.println(uur + “:” + min + “:” + sec ); return ; } Inleiding Informatica

Prof. Dr. O. De Troyer

public void drukafVerkeerd() { String st = uur + “:” + min + “:” + sec ; return ; System.out.println (st) ; } 45

Return waarde • Methoden kunnen slechts één waarde terug geven – return uur, min, sec kan niet – Oplossing: zie later

Inleiding Informatica

Prof. Dr. O. De Troyer

46

public versus private • private

verhindert dat de methode of variabele buiten de klasse kan worden gebruikt

• public

laat gebruik van de methode of variabele buiten de klasse toe • In ‘t algemeen: – Methoden uit de interface zijn “public” – Hulp-methoden zijn “private” – Instantie variabelen zijn “private”

Inleiding Informatica

Prof. Dr. O. De Troyer

47

Toegankelijkheid en zichtbaarheid • Lokale variabelen zijn niet toegankelijk buiten de methode • Ze zijn ook niet zichtbaar buiten de methode public void methode1() { String s = “test1” ; ... } public void methode2 () { String s = “test2” ; … } Inleiding Informatica

Prof. Dr. O. De Troyer

Draagwijdte (scope) van deze s Twee verschillende variabelen

Draagwijdte (scope) van deze s

48

De levensduur van een object • Het “leven” van een object begint bij de creatie van het object – door de new operator • Een object blijft “leven” zolang er ten minste één referentie variabele naar verwijst. • Java vernietigt automatische alle objecten waarnaar niet meer gerefereerd wordt

Inleiding Informatica

Prof. Dr. O. De Troyer

49

Voorbeeld Referentie naar “herfst” is weg! Java zal “herfst” object vernietigen.

String

t

t;

t = “herfst” ;

“herfst”

t = “winter” ; “winter”

Inleiding Informatica

Prof. Dr. O. De Troyer

50

Levensduur van variabelen (1) • Instantie variabelen worden samen met het object gecreëerd – De levensduur is dus gelijk aan de levensduur van het object Instantie variabelen Object Toestand Kleur: “blauw” Merk: “Opel” Nummerplaat: “ARJ775” Gedrag Rijden Remmen Toeteren

Inleiding Informatica

Prof. Dr. O. De Troyer

51

Levenduur van variabelen (2) • Parameters en lokale variabelen van een methode worden gecreëerd wanneer de methode aangeroepen wordt • Ze worden vernietigd als de uitvoering van de methode stopt Levensduur van s1, s2 en hulp Activatie methode

Einde methode

tijd

Public void m(String s1, String s2) { String hulp; ... Inleiding Informatica

Prof. Dr. O. De Troyer

52

this

• Een bericht wordt naar een object gestuurd. • Om binnen een methode naar dit object te refereren gebruiken we “this” this.doeIets • this ook te gebruiken om een onderscheid te maken tussen instantie variabele en lokale variabele met dezelfde naam class … { public void methode1 { String s ; Lokale variabele s … s Welke s? } private String s

} Inleiding Informatica

- s voor lokale s - this.s voor instantie variabele s

Instantie variabele s Prof. Dr. O. De Troyer

53

Voorbeeld 2 - klasse ontwerp • Ontwerp een klasse voor het behandelen van namen: Name

Inleiding Informatica

Prof. Dr. O. De Troyer

54

Klasse Name - Bepaal het gedrag • We willen het volgende gedrag – Geef de initialen van de naam (als string) – Voeg een titel (Mr, Mrs, …) toe of vervang die – Geef de naam in familienaam-voornaam formaat (als string) – Geef de naam in titel-voornaamfamilienaam formaat (als string)

Inleiding Informatica

Prof. Dr. O. De Troyer

55

Name vb - Bepaal de interface – Class name: Name – Constructor: vb: Name ik = new Name(“Olga”, “De Troyer”); public Name(String first, String last) – Geef initialen: vb: String inits = ik.getInitials(); public String getInitials() – Geef familienaam, voornaam: vb: String s = ik.getLastFirst(); public String getLastFirst() – Geef titel, voornaam, familienaam: vb: String s = ik.getFirstLast(); public String getFirstLast() – Voeg titel toe: vb: String s = ik.setTitle(“Prof. Dr.”); public void setTitle(String newTitle);

Inleiding Informatica

Prof. Dr. O. De Troyer

56

Name vb - Een vb-programma Schrijf een programma met 3 strings (voornaam, achternaam, titel); hiervan een naam maakt; deze 3 strings op een lijn schrijft gevolgd door de naam in familienaam-voornaam formaat; de initialen; de naam in voornaam- familienaam formaat; telkens op een nieuwe lijn import java.io.*; class IllustrateName { public static void main(String[] arg) throws IOException { Name n; String first, last, title ; first = “Vera” last = “Janssens“; title = “Dr “;

Inleiding Informatica

Prof. Dr. O. De Troyer

57

Name vb - Een vb-programma (2) //maak de naam n = new Name(first, last); n.setTitle(title); //schrijf de 3 strings op een lijn System.out.print(first); System.out.print(last); System.out.println(title); //schrijf familienaam voornaam System.out.println(n.getLastFirst()); //schrijf initialen System.out.println(n.getInitials());

}

//schrijf voornaam familienaam System.out.println(n.getFirstLast()); }

Inleiding Informatica

Prof. Dr. O. De Troyer

58

Name vb - Klasse skelet class Name { instantie variabelen indien nodig public Name( String first, String last ) { statements } //geef initialen public String getInitials( ) { statements } // geef voornaam, familienaaam public String getFirstLast( ) { statements } // geef familienaam, voornaaam public String getLastFirst( ) { statements } // voeg titel toe public void setTitle( String newTitle) { statements } } Inleiding Informatica

Prof. Dr. O. De Troyer

59

Name vb - Implementatie • Hoe de naam bijhouden? – Instantie variabel(en) – 1 of 3 ? private String firstName; private String lastName; private String title;

• Hoe waarde geven? – Via constructor

public Name( String first, String last) { firstName = first ; lastName = last ; title = ? ; title = ” ” ; }

Inleiding Informatica

Prof. Dr. O. De Troyer

60

Name vb - Implementatie (2) public void setTitle( String newtitle) { title = newtitle ; } public String getLastFirst ( ) { return lastName.concat(“, “).concat(firstName); } public String getFirstLast ( ) { return title.concat(“ “). concat(firstName). concat(“ “).concat(lastName); } public String getInitials ( ) { String s ; s = firstName.substring(0,1) ; s = s.concat(“.”); s = s.concat( lastName.substring(0,1)); s = s.concat(“.”); return s ; }

Inleiding Informatica

Prof. Dr. O. De Troyer

61

Name vb - voorbeeld programma Maak 2 Name-objecten met voornaam “Olga”, familienaam “De Troyer”, resp. “Dirk”, “De Troyer” en schrijf ze uit in het familienaamvoornaam formaat telkens op een nieuwe lijn.

import java.io.* ; class program4 { public static void main(String arg [] ) throw IOException { Name n1 , n2 ; n1 = new Name(“Olga”, “De Troyer”); n2 = new Name(“Dirk”, “De Troyer”); System.out.println(n1.getLastFirst()); System.out.println(n2.getLastFirst()); } }

Twee Name-objecten elk met hun eigen instantie variabelen (= hun toestand)

Inleiding Informatica

Prof. Dr. O. De Troyer

62

Klasse methoden • Nieuwe instantie van een klasse maken – Geen object-ontvanger !

• Bericht kan niet naar een object gestuurd worden • Bericht wordt naar de klasse gestuurd  Klasse methode

Inleiding Informatica

Prof. Dr. O. De Troyer

63

Klasse methoden (2) • Worden gedefinieerd zoals andere methoden maar met het sleutelwoord static voor het return-type – Ook wel statische methoden genoemd public static int klasseMethode () { … }

Inleiding Informatica

Prof. Dr. O. De Troyer

64

Programma’s en Klasse methoden ... import java.io.*; class Programma1 { public static void main (String[] arg) { System.out.println(“Dit is mijn eerste Java programma”); System.out.println(“maar niet mijn laatste.”); } }

• Een programma is een klasse • Zo een klasse heeft een main-methode • De main-methode is een klasse methode

– Er bestaan immers geen objecten bij aanvang van een programma

Inleiding Informatica

Prof. Dr. O. De Troyer

65

Klasse variabelen • Een klasse attribuut of klasse variabele is een attribuut gemeenschappelijk aan alle instanties van een klasse. • Dus eigenlijk een attribuut van de klasse • Worden aangeduid door het sleutelwoord static

Inleiding Informatica

Prof. Dr. O. De Troyer

66

Klasse variabelen - voorbeeld • Voorbeeld - Name klasse: Veronderstel een maximale lengte voor de namen class Name { public Name( String first, String last ) { ... } public String getInitials( ) { ... } public String getFirstLast( ) { … } public String getLastFirst( ) { ... } public void setTitle( String newTitle) { ... } private String firstName; private String LastName; private String title;

static maxNameLength = 50 ;

Inleiding Informatica

Prof. Dr. O. De Troyer

Klasse variabele 67

Klasse variablen - voorbeeld (2) public boolean testLength( String s ) { if (s.length()
View more...

Comments

Copyright � 2017 NANOPDF Inc.
SUPPORT NANOPDF