Diskuze – Lekce 2 - První objektová aplikace v Javě - Hello object world
ZpětUpozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.


Michal Šmahel:24.7.2019 18:27
Ahoj, jsem moc rád, že se zajímáš o kvalitu svého kódu a nebojíš se zde zeptat. Jako začátečník děláš různé zbytečné chyby (i vážnějšího charakteru) a je dobré o nich vědět, aby ses jim příště mohl vyvarovat. Neber to prosím jako kritiku, ale spíše jako doporučení. Když jsem začínal, dělal jsem také podobné věci. Není na tom nic špatného, jen je třeba na sobě stále pracovat a tyto chyby eliminovat. Doporučuji si tyto zdrojové kódy někam uložit a podívat se na ně po nějaké době, jistě zaznamenáš velký pokrok.
Tedy k věci. Nejprve přikládám pozměněný kód. Opravím chyby, které jsi udělal a následně uvedu zdůvodnění.
Main třída:
package kalkulacka_objekt;
import java.util.Scanner;
/**
*
* @author Danie
*/
public class Kalkulacka_objekt {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Kalkulator kalkulator = new Kalkulator();
Scanner sc = new Scanner(System.in, "Windows-1250");
/* O tom, zda se má pokračovat třída Kalkulator vůbec nerozhoduje
* Již z názvu vypovídá, že je to třída, která bude kalkulovat (počítat),
* do běhu řídícího cyklu (ten while, co máš níže) nemá co zasahovat
* navíc je zbytečné využívat String. Tato proměnná nabývá pouze 2 hodnot,
* což napovídá datový typ boolean (ano -> true, ne -> false)
* Výsledek není třeba inicializovat ani neklarovat
*/
boolean pokracovat = true;
System.out.println("Vítejte v kalkulačce");
/* Tady se musí změnit podmínka kvůli tomu, že už se stav pokračování
* uchovává úplně jinak
* Můžeš si představit jako: while(pokracovat == true) {
*/
while(pokracovat){
System.out.println("Zadejte první číslo");
float a = Float.parseFloat(sc.nextLine());
System.out.println("Zadejte druhé číslo:");
float b = Float.parseFloat(sc.nextLine());
System.out.println("Zvolte si operaci:");
System.out.println("1 - sčítání");
System.out.println("2 - odčítání");
System.out.println("3 - násobení");
System.out.println("4 - dělení");
// Je lepší mít ty názvy proměnných přesnější
int operace = Integer.parseInt(sc.nextLine());
/* Výsledek nepředáváme, je to k ničemu,
* ten teprve metoda vypocitej() spočítá
*/
System.out.println(kalkulator.vypocitej(operace, a, b));
System.out.println("Přejete si pokračovat? A/n");
/* Opět kvůli změně výše
* Dalo by se zkrátit na: pokracovat = (Character.parseChar(sc.nextLine()) === 'A');
*/
if(Character.parseChar(sc.nextLine()) == 'A')
{
pokracovat = true;
}
else
{
pokracovat = false;
}
}
System.out.println("Děkuji za využití kalkulačky");
}
}
Třída Kalkulator:
package kalkulacka_objekt;
/**
*
* @author Danie
*/
public class Kalkulator {
/* Tady to chce lepší název metody - měl by to být nějaký rozkaz
* Název parametru volba opět není nejlepší
* Není důvod k předávání výsledku - ten se teprve vypočítá
*/
public String vypocitej(int operace, float a, float b){
/* Tohle je lepší mít hned na začátku, pokud se uvede chybná volba,
* mělo by se ihned skončit (nemá smysl pokračovat dál)
* Skončí se tak, že se zavolá return
*/
if ((volba < 0) || (volba > 5))
{
/* Tady je String.format() zbytečné, to se používá při vkládání proměnné
* do řetězce
*/
return "Neplatná volba";
}
float vysledek;
/* Tohle bych řešil spíše přes switch - potom bys nemusel mít
* ani podmínku nad deklarací proměnné vysledek, ale využil bys
* výchozí volbu (default)
* Velkou výhodou je, že nemusíš upravovat okolní kód, když chceš
* přidat novou operaci nebo nějakou odebrat
*/
if (operace == 1)
{
vysledek = a + b;
}
else if (operace == 2)
{
vysledek = a - b;
}
else if (operace == 3)
{
vysledek = a * b;
}
else if (operace == 4)
{
// TODO: Ošetřit dělení nulou
vysledek = a / b;
}
/* Nyní již můžeš vklidu vrátit výsledek
* Také zde vidíš použití metody String.format()
*/
return String.format("Výsledek: %f", vysledek);
}
}
Většinu věcí jsem nakonec sepsal přímo do kódu. Jen ještě doplním, že je dobré si dělat mezery v kódu pro větší přehlednost. Obvykle po nějakém "bloku" kódu. To není povinné, ale potom se v tom lépe orientuješ. Sice už tam není třídní vlastnost pokracovat, ale stejně k ní něco zmíním. V Javě je třeba psát většinu vlastností jako privátní nebo protected. Tímto porušuješ zapouzdření. V ideálním případě by k vlastnostem přímo (Trida.vlasnost) měla mít přístup jen daná třída. Ostatní by měly využívat pomocné metody - gettery a settery (v dalších článcích je to dobře rozepsané). Také je občas dobré se zamyslet nad pořadím příkazů. Často tím, že nejprve ověříš vstupní parametry metody, ušetříš mnoho času počítači i sobě. Ty nebudeš muset ošetřovat stavy, které by mohly dále vzniknout a počítač úlohu dříve dokončí. Také dávej pozor na pojmenování proměnných, parametrů, metod apod. Je třeba, aby to bylo jasné, výstižné a co nejjednodušší. Zase to pomáhá orientaci v kódu a obecné přehlednosti.
No, to by bylo asi vše. V klidu si to projdi, pročti si mé poznámky a zkus si uvědomit dané chyby. Pokud se stane, že něco nepochopíš, ještě mi odepiš, rád cokoliv doplním.
muzete mi pomoci? pokazde mi to vraci vysledek 0.
package com.company;
import java.util.Scanner;
public class Kalkulator {
private float a;
private float b;
private int volba;
public void privitani() {
System.out.println("Vitejte v kalkulacce!!!");
}
public void podekovani() {
System.out.println("Dekujeme za pouziti kalkulacky");
}
public void zobrazeni() {
System.out.println("1-scitani");
System.out.println("2-odcitani");
System.out.println("3-deleni");
System.out.println("4-nasobeni");
}
public float vypocet() {
float vysledek =0;
switch (volba) {
case 1: vysledek=a+b;
break;
case 2: vysledek=a-b;
break;
case 3: vysledek=a/b;
break;
case 4:vysledek=(a*b);
break;
}
return vysledek;
}
}
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Kalkulator kalkulator=new Kalkulator();
Scanner sc=new Scanner(System.in,"Windows-1250");
String pokracovat="ano";
while(pokracovat.equals("ano")){
kalkulator.privitani();
System.out.println("Zadejte prvni cislo");
float a=Float.parseFloat(sc.nextLine());
System.out.println("Zadejte druhe cislo");
float b=Float.parseFloat(sc.nextLine());
kalkulator.zobrazeni();
System.out.println("Vyberte operaci");
int volba=Integer.parseInt(sc.nextLine());
if ((volba>0)&&(volba<5)) {
System.out.printf("Vysledek je %f ", kalkulator.vypocet());
}
else{
System.out.printf("spatne zadani");
}
System.out.println();
kalkulator.podekovani();
System.out.printf("Prejete si pokracovat? ano/ne");
pokracovat = sc.nextLine();
}
}
}
Daniel Holotík:25.7.2019 2:05
Wow, skvělý!
Děkuji ti moc za to, že jsi si na mě udělal čas.
Takhle teď v noci jsem si to narychlo projel a všemu jsem zatím porozuměl. Odpoledne se na to podívám důkladněji a kdyžtak ještě napíšu .)
Michal Šmahel:25.7.2019 12:28
Ahoj, v metodě Kalkulator.vypocet() ti chybí parametr volba. Takhle v proměnné volba (ve zmiňované metodě) není žádná hodnota. Tím pádem se switch vlastně vynechá, protože neobsahuje tu neexistující hodnotu. No a vrátí se výchozí hodnota výsledku - 0.
MAIN
package opp.kalkulacka;
public class OppKalkulacka {
public static void main(String[] args) {
Vypocty vypocty = new Vypocty();
System.out.println("KALKULAČKA");
do{
System.out.print("První číslo : ");
vypocty.zapisCisloJedna();
System.out.print("Zadej operaci : ");
vypocty.zapisSymbol();
System.out.print("Druhe číslo : ");
vypocty.zapisCisloDva();
vypocty.provedOperaci();
System.out.print("Chcete zadání opakovat? [ANO|NE] : ");
vypocty.opakujKalkulacku();
} while (vypocty.opakovani == true);
}
}
TŘÍDA
package opp.kalkulacka;
import java.util.Scanner;
public class Vypocty {
Scanner sc = new Scanner(System.in,"Windows-1250");
float prvniCislo;
float druheCislo;
String symbol;
float vysledek = 0;
boolean opakovani = true;
public void zapisCisloJedna(){
prvniCislo = Float.parseFloat(sc.nextLine());
}
public void zapisCisloDva(){
druheCislo = Float.parseFloat(sc.nextLine());
}
public void zapisSymbol(){
symbol = sc.nextLine().trim();
}
public void provedOperaci(){
switch (symbol){
case "+":
vysledek = prvniCislo + druheCislo;
break;
case "-":
vysledek = prvniCislo - druheCislo;
break;
case "/":
vysledek = prvniCislo / druheCislo;
break;
case "*":
vysledek = prvniCislo * druheCislo;
break;
default: System.out.println("Chybná operace");
return;
}
System.out.println("Vysledek : " + vysledek);
}
public void opakujKalkulacku(){
String zadani = sc.nextLine().trim().toLowerCase();
if (zadani.equals("ne")){
opakovani = false;
}
}
}
Ahoj můžete mi prosím
někdo vysvětlit tu metodu toString() ?, vůbec to nechápu.
Alesh:27.3.2020 21:05
Máš to vysvětleno ve Lekce 3 - Hrací kostka v Javě - konstruktory a náhodná čísla, konkrétně hledej odstavec nazvaný "Překrývání metody toString()".
Protože jsem laik a všechno se učím sám mám možná hloupý dotaz. Jak moc má být objektové programování objektové? Uvedu dva příklady. Pokaždé se jedná o pouhé přesunutí proměnných X a Y do proměnných A a B. Co je podle vás lepší a proč?
private int X;
private int Y;
private int A;
private int B;
public void zapisPromenne(){
A = X;
B = Y;
}
a teď to stejné ale více objektově
private int X;
private int Y;
private int A;
private int B;
public int getX(){
return x;
}
public int getY(){
return y;
}
private void setA(int r){
a = r;
}
private void setB(int s){
b = s;
}
public void presunPromenych(){
setA(getX());
setB(getY());
}
Děkuji všem za informace.
Zobrazeno 10 zpráv z 196.