001    package de.hska.java.aufgaben.objekte;
002    
003    /**
004     * Ein Chemisches Element mit seinem symbolischen Namen (ersten Buchstaben
005     * des lateinischen Namens) und  der Kernladungszahl.
006     * Die Objekte dieser Klasse sind unveränderlich.
007     * 
008     * <p>
009     *   <a href="http://www.home.hs-karlsruhe.de/~pach0003/informatik_1/aufgaben/objekt_orientierung.html#chemisches_element">Zurück zum Aufgabentext</a>
010     * </p>
011     * 
012     * @author Christian Pape
013     */
014    public class ChemischesElement implements Comparable {
015    
016        private String symbol = "";
017        
018        /**
019         * Anzahl Protonen, auch Ordnungszahl
020         */
021        private int kernladungszahl = 1;
022        
023        /**
024         * Dieser Wert ist ein Maß dafür,
025         * wie stark ein Element Bindunselektronen an sich zu ziehen vermag.
026         */
027        private double elektroNegativitaet;
028        
029        public static final ChemischesElement WASSERSTOFF = new ChemischesElement("H", 1, 2.20);
030    
031        public static final ChemischesElement SAUERSTOFF = new ChemischesElement("O", 8, 3.44);
032    
033        public static final ChemischesElement KALIUM = new ChemischesElement("K", 19, 0.82);
034        
035        public static final ChemischesElement ZINK = new ChemischesElement("Zn", 30, 1.65);
036        
037        public static final ChemischesElement GALLIUM = new ChemischesElement("Ga", 31, 1.81);
038        
039        private static boolean [] alkalimetall = new boolean[119];
040        
041        static {
042            alkalimetall[3] = true;
043            alkalimetall[11] = true;
044            alkalimetall[19] = true;
045            alkalimetall[37] = true;
046            alkalimetall[55] = true;
047            alkalimetall[85] = true;
048        }
049        
050        /**
051         * Erzeugt ein neues Chemisches Element mit dem
052         * gegebenen symbolischen Namen und der Kernladungszahl
053         * (Ordnungszahl bzw. Anzahl Protonen).
054        */
055        public ChemischesElement(String symbol, int kernladungszahl,
056                double elektronenNegativitaet)  {
057            this.symbol = symbol;
058            this.kernladungszahl = kernladungszahl;
059            this.elektroNegativitaet = elektronenNegativitaet;
060        }
061        
062        /**
063         * Erzeugt ein neues Chemisches Element mit dem gegebenen
064         * Symbol und Kernladungszahl sowie der Elektronennegativität 0.
065         */
066        public ChemischesElement(String symbol, int kernladungszahl) {
067            this(symbol, kernladungszahl, 0);
068        }
069        
070        /**
071         * Gibt genau dann true zurück, wenn dieses Chemische Element
072         * ein Metall ist.
073         */
074        public boolean isMetall() {
075            boolean metall = false;
076            
077            switch (kernladungszahl) {
078            case 13:
079            case 31:
080            case 49:
081            case 50:
082            case 81:
083            case 82:
084            case 83:
085            case 113:
086            case 114:
087            case 115:
088            case 116: metall = true;
089            }
090            return metall;
091        }
092        /**
093         * Gibt genau dann true zurück, wenn dieses Chemische Element
094         * ein Alkalimetall ist.
095         */
096        public boolean isAlkalimetall() {
097            // Dies ist die schnellste Variante.
098            // Da die Initialisierung an einem anderen Ort ist,
099            // ist die Wartbarkeit dieser Methode etwas schlechter
100            // als die beiden anderen Implementierungen
101            return alkalimetall[kernladungszahl];
102        }
103    
104        /**
105         * Gibt genau dann true zurück, wenn dieses Chemische Element
106         * ein Übergangsmetall ist. 
107         */
108        public boolean isUebergangsmetall() {
109            return 21 <= kernladungszahl && kernladungszahl <= 30
110                || 39 <= kernladungszahl && kernladungszahl <= 48
111                || 72 <= kernladungszahl && kernladungszahl <= 80;
112        }
113        
114        /**
115         * Gibt den symbolischen Namen (ein oder zwei Anfangsbuchstaben
116         * des lateinischen Namens) dieses Chemischen Elements zurück.
117         */
118        public String getSymbol() {
119            return symbol;
120        }
121        
122        /**
123         * Gibt die Kernladungszahl (auch Ordnungszahl bzw. die Anzahl
124         * Protonen) dieses Chemischen Elementes zurück.
125         */
126        public int getKernladungszahl() {
127            return kernladungszahl;
128        }
129        
130        public double getElektroNegativitaet() {
131            return elektroNegativitaet;
132        }
133        
134        public String toString() {
135            return getSymbol();
136        }
137        /**
138         * Vergleicht zwei chemische Elemente hinsichtlich ihrer
139         * Elektronennegativität. 
140         * In der Summenformel werden die Atome aufsteigend hinsichtlich
141         * ihrer Elektronennegativität angeordnet:
142         * NaCl für Kochsalz, da Natrium eine geringe Elektronennegativität als
143         * Chlor hat.
144         * </p>
145         * Im sogenannten Hill-System hingegen werden Elemente weitgehend
146         * lexikographisch nach ihrem Symbol angeordnet (ausser bei Kohlenstoffverbindungen,
147         * dort kommt erst C dann H, lediglich der Rest ist dann rein lexikographisch).
148         * Dies läßt sich aber nicht mehr durch eine Comparable implementieren,
149         * da bei Methodenaufruf für zwei Elemente nicht bekannt ist, ob überhaupt ein Kohlenstoffatom
150         * vorhanden ist: der Vergleich H mit Cl ist zum Beispiel dann nicht 
151         * zu berechnen.
152         */
153        public int compareTo(Object o) {
154            ChemischesElement element = (ChemischesElement) o;
155            
156            // Beachte: Geleitkommazahlen nicht mit der Identität überprüfen
157            if ( Math.abs(elektroNegativitaet - element.elektroNegativitaet) <= 0.000000000001) {
158                return 0;
159            } else if ( elektroNegativitaet < element.elektroNegativitaet) {
160                return -1;
161            } else {
162                return 1;
163            }
164        }
165    
166        
167     
168    }