برنامه نویسی

برنامه نویسی شی گرا – جاوا

Summarize this content to 400 words in Persian Lang
ماهیت OOP ایجاد مدل هایی از اشیاء دنیای واقعی در نرم افزار است. اشیاء می توانند چیزهای ملموسی باشند، مانند ماشین، یا انتزاعی تر، مانند تراکنش بانکی. هر شی دارای حالات و رفتارهایی است. حالت ها ویژگی هایی هستند که شی را تعریف می کنند، در حالی که رفتارها اعمالی هستند که می تواند انجام دهد.

به عنوان مثال، کلاس خودرو را تصور کنید. یک خودرو دارای ویژگی هایی است که ویژگی های آن را توصیف می کند، مانند:

رنگ (حالت)،
نام تجاری (ایالت)،
مدل (حالت)،
تعداد پورت ها (حالت).

علاوه بر این، یک ماشین همچنین می تواند اقداماتی مانند:

تماس (رفتار)
راه رفتن (رفتار)
توقف (رفتار).

در اینجا کلاس Car تعریف می کند که هر خودرو (شیء) چه چیزی باید داشته باشد و چه کاری می تواند انجام دهد. ما می‌توانیم هر تعداد خودرو که بخواهیم از این کلاس بسازیم که هر کدام ویژگی‌ها و رفتارهای خاص خود را دارند، اما همیشه از «طرح‌بندی» تعریف‌شده توسط کلاس پیروی می‌کنند.

نمونه ای از نحوه ایجاد این در جاوا به شرح زیر است:

public class Carro {

String marca;
String modelo;
String cor;
int quantidade_de_portas;

// inicializamos a classe Carro sem nenhum valor inicial
public Carro(Strin) {
}
}

public static void main(String[] args) {
Carro carro_exemplo = new Carro(“Volkswagen “, “Gol”, “prata”, 4);
Carro carro_exemplo2 = new Carro(“Fiat”, “Uno”, “prata”, 2);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کپسولاسیون

کپسوله‌سازی در جاوا یکی از ارکان برنامه‌نویسی شی گرا (OOP) است و به عمل محدود کردن دسترسی مستقیم به ویژگی‌های یک کلاس اشاره دارد و واضح‌تر می‌کند که کدام قسمت‌های یک شی می‌تواند مستقیماً به آن دسترسی یا تغییر دهد. با آن می توانیم استفاده و دستکاری داده ها را کنترل کنیم و امنیت و یکپارچگی بیشتری را تضمین کنیم.

در جاوا کپسوله سازی از طریق اصلاح کننده های دسترسی مانند privateه publicو با استفاده از متدهای خاص، معروف به getters و setter، که امکان دسترسی یا تغییر ویژگی های یک کلاس را به صورت کنترل شده فراهم می کند.

در مثال زیر:

کلاس ContaBancaria شامل دو ویژگی Holder و balance است. همانطور که هر دو با اصلاح کننده اعلام می شوند public، آنها را می توان مستقیماً از هر بخشی از سیستم، بدون هیچ گونه کنترل یا اعتبارسنجی، به آنها دسترسی داشت و تغییر داد. این می تواند خطرناک باشد زیرا داده های حساس را می توان در زمان های نامناسب یا نادرست تغییر داد.

اکنون، با استفاده از کپسوله سازی، می توانیم از این داده ها محافظت کنیم:

public class ContaBancaria {
private String titular;
private double saldo;

// Getter
public String getTitular() {
return titular;
}

public double getSaldo() {
return saldo;
}

// Setter
public void setTitular(String titular) {
this.titular = titular;
}

public void setSaldo(double saldo) {
this.saldo = saldo;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، ویژگی های نگهدارنده و تعادل به اصلاح شد private، به این معنی که نمی توان مستقیماً از خارج از کلاس ContaBancaria به آنها دسترسی داشت. در عوض، ما روش هایی را ایجاد می کنیم دریافت کنید ه مجموعه برای هر یک از این ویژگی ها، که اجازه دسترسی کنترل شده را می دهد. به عنوان مثال، این امر از تغییر مستقیم تعادل توسط هر بخشی از سیستم بدون گذر از قوانین تجاری یا اعتبار سنجی جلوگیری می کند.

مهم است که تأکید کنیم هر زمان که ما نیاز به کنترل نحوه ارائه داده برای کسانی که از خارج به مقداری از این کلاس دسترسی دارند، از دریافت کننده استفاده می شود. به همین ترتیب، تنظیم کننده برای پیاده سازی تغییرات به روشی ایمن تر و محدودتر در ویژگی ها ایجاد می شود و اجازه می دهد تا قوانین یا اعتبارسنجی ها قبل از تغییر مقادیر اعمال شوند.

اکنون، برای دسترسی یا اصلاح ویژگی های ContaBancaria، کد باید متدهای مناسب را فراخوانی کند:

ContaBancaria conta = new ContaBancaria();
conta.setTitular(“Felipe”);
conta.setSaldo(0.0);

System.out.println(conta.getTitular());

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این کار، ما تضمین می کنیم که تنها راه تغییر نگهدارنده یا بالانس از طریق روش های خاصی است که سیستم را در برابر تغییرات یا خطاهای ناخواسته محافظت می کند، مانند:

conta.titular = “Bruno”;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

میراث

وراثت یکی از ارکان اساسی برنامه نویسی شی گرا (OOP) است. مفهوم وراثت به یک کلاس (به نام زیر کلاس) اجازه می دهد تا ویژگی ها و رفتارها را از کلاس دیگر (به نام سوپرکلاس) به ارث ببرد. با وراثت، امکان استفاده مجدد و تخصصی کردن کد موجود وجود دارد که توسعه سیستم ها را کارآمدتر و سازماندهی می کند.

وراثت چگونه مفید است؟

تصور کنید کلاسی به نام Card دارید که دارای ویژگی ها و رفتارهای مشترک در انواع مختلف کارت ها مانند کارت های بدهی و اعتباری است. به جای تکرار این ویژگی ها و رفتارها در هر نوع کارت، می توانید آنها را در کلاس Card متمرکز کنید و سپس این ویژگی ها را در زیر کلاس ها به ارث ببرید. CartaoDebito ه CartaoCredito.

مثال زیر:

در نمودار بالا، کلاس Cartao دارای سه ویژگی مشترک است: codigo_cartao، numero_cartao ه digito_cartao. این ویژگی ها به عنوان علامت گذاری شده اند protected، که به این معنی است که می توان آنها را مستقیماً توسط زیر کلاس ها در دسترس قرار داد و تغییر داد، اما توسط سایر کلاس های خارجی نمی توان آنها را تغییر داد.

حالا دو زیر کلاس داریم:

کارت بدهی: ویژگی های کلاس را به ارث می برد Cartao و رفتارها و صفات خاصی مانند data_pagamento_deposito ه data_saqueو همچنین روش های برداشت و واریز پول.

کارت اعتباری: همچنین ویژگی های Cartao را به ارث می برد، اما ویژگی های خاصی را اضافه می کند، مانند se_pode_aproximacao و رفتارهای پرداخت با/بدون تماس و بررسی محدودیت کارت.

در این مثال، کلاس ها CartaoDebito ه CartaoCredito ویژگی ها و متدها را از کلاس به ارث می برند Cartao. به این ترتیب، ما از کد پایه سوپرکلاس استفاده مجدد می کنیم، که نگهداری و توسعه را ساده می کند. علاوه بر این، هر زیر کلاس می‌تواند نسخه‌های روش‌های خاص خود را پیاده‌سازی کند یا رفتارهای جدید خاصی را اضافه کند و انعطاف‌پذیری و تخصص مورد نیاز برای هر نوع کارت را تضمین کند.

مثال زیر:

public abstract class Cartao {
protected String codigo_cartao;
protected String numero_cartao;
protected String digito_cartao;

// Métodos comuns
public abstract void sacarDinheiro(double valor);
public abstract void depositarDinheiro(double valor);
}

// Subclasse Cartão de Débito
public class CartaoDebito extends Cartao {
private String data_deposito;
private String data_saque;

@Override
public void sacarDinheiro(double valor) {
System.out.println(“Sacando dinheiro do Cartão de Débito”);
// Lógica específica para o saque
// Adicionar data de saque;
}

@Override
public void depositarDinheiro(double valor) {
System.out.println(“Depositando dinheiro no Cartão de Débito”);
// Lógica específica para o depósito
// Adicionar data de deposito;
}
}

// Subclasse Cartão de Crédito
public class CartaoCredito extends Cartao {
private String data_pagamento;
private boolean se_pode_aproximacao;

@Override
public void sacarDinheiro(double valor) {
System.out.println(“Sacando dinheiro do Cartão de Crédito”);
// Lógica específica para o saque
}

@Override
public void depositarDinheiro(double valor) {
System.out.println(“Depositando dinheiro no Cartão de Crédito”);
// Lógica específica para o depósito
}

public void pagar() {
if (se_pode_aproximacao) {
System.out.println(“Pagamento com aproximação”);
} else {
System.out.println(“Pagamento sem aproximação”);
}
// Adiciona data de pagamento;
}

public void verificarSeTemLimite() {
// Lógica para verificar o limite do cartão
System.out.println(“Verificando limite do Cartão de Crédito”);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، کلاس ها CartaoDebito ه CartaoCredito ویژگی ها و متدها را از کلاس Cartao به ارث می برند. به این ترتیب، ما از کد پایه سوپرکلاس استفاده مجدد می کنیم، که نگهداری و توسعه را ساده می کند. علاوه بر این، هر زیر کلاس می‌تواند نسخه‌های روش‌های خاص خود را پیاده‌سازی کند یا رفتارهای جدید خاصی را اضافه کند و انعطاف‌پذیری و تخصص مورد نیاز برای هر نوع کارت را تضمین کند.

چند شکلی

اکنون که وراثت را درک کردیم، بیایید در مورد چیزی صحبت کنیم که بسیار به آن مرتبط است، یعنی چند شکلی به عبارت ساده به معنای “شکل های متعدد” است – یعنی توانایی یک شی برای به خود گرفتن اشکال مختلف. در زمینه OOP، پلی مورفیسم به همان عمل (مانند استفاده از یک رویه) اجازه می دهد تا بسته به شیئی که آن را انجام می دهد، به روش های مختلف رفتار کند.

این بسیار مفید است زیرا به ما امکان می دهد با اشیاء مختلف به طور یکنواخت رفتار کنیم، اما همچنان به هر شی اجازه می دهد تا رفتار خاص خود را داشته باشد.

در مثالی که قبلا دیدیم، یک کلاس پایه به نام Cartao داریم که توسط دو کلاس گسترش می‌یابد: CartaoDebito ه CartaoCredito. هر یک از این زیر کلاس ها رفتارهای مخصوص به نوع کارت را پیاده سازی می کنند، مانند sacarDinheiro() ه depositarDinheiro().

حال، بیایید ببینیم چگونه می توان از چندشکلی برای رفتار با انواع مختلف کارت ها به روشی یکنواخت استفاده کرد، اما به هر کارت اجازه می دهد تا مطابق با ویژگی های خود عمل کند.

public class Main {
public static void processarSaque(Cartao cartao, double valor) {
cartao.sacarDinheiro(valor);
}

public static void processarDeposito(Cartao cartao, double valor) {
cartao.depositarDinheiro(valor);
}

public static void main(String[] args) {
Cartao cartaoDebito = new CartaoDebito();
Cartao cartaoCredito = new CartaoCredito();

// Polimorfismo em ação: o método sacarDinheiro se comporta de maneira diferente para cada tipo de cartão
processarSaque(cartaoDebito, 100); // Comportamento específico do Cartão de Débito
processarSaque(cartaoCredito, 200); // Comportamento específico do Cartão de Crédito

processarDeposito(cartaoDebito, 500); // Depósito no Cartão de Débito
processarDeposito(cartaoCredito, 1000); // Depósito no Cartão de Crédito
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در کد بالا دو متد به نام داریم processarSaque ه processarDeposito. این متدها یک شی از نوع دریافت می کنند Cartao به عنوان یک آرگومان، به این معنی که آنها می توانند هر زیر کلاسی را بپذیرند Cartao، مانند CartaoDebito یا CartaoCredito.

رفتار چند شکلی زمانی اتفاق می افتد که متد را فراخوانی کنیم sacarDinheiro() ه depositarDinheiro() در انواع مختلف کارت حتی اگر روش ها به یک شکل نامیده می شوند، رفتار بر اساس نوع شی تغییر می کند (خواه a CartaoDebito یا الف CartaoCredito). این چند شکلی در عمل است – روش بسته به شیئی که آن را فراخوانی می کند متفاوت رفتار می کند.

چند شکلی کد را انعطاف پذیرتر و مقیاس پذیرتر می کند. توجه داشته باشید که در مثال، روش‌هایprocessWithdraw andprocessDeposito برای مقابله با انواع مختلف کارت‌ها نیازی به تغییر یا تکرار ندارند. آنها هر شیئی را که نمونه ای از کلاس باشد می پذیرند Cartao، و رفتار مناسب است به صورت پویا تصمیم گرفت، بر اساس نوع کارت خاص.

رابط

رابط، آخرین اما نه کم اهمیت ترین، یکی از ارکان برنامه نویسی شی گرا (OOP) است و به طور گسترده مورد استفاده قرار می گیرد. این اثر معکوس وراثت دارد: در حالی که وراثت به کلاس فرزند اجازه می دهد تا ویژگی های کلاس والد را به ارث ببرد، رابط تمام کلاس هایی را که آن را پیاده سازی می کنند مجبور می کند تا منطق خود را برای متدهای تعریف شده ارائه کنند. این تضمین می‌کند که هر کلاس با یک قرارداد خاص مطابقت دارد، و ثبات و استفاده مجدد از کد را ارتقا می‌دهد.

مثال زیر:

در این مثال، ما رابطی به نام داریم Notificacao، که متدی به نام دارد enviarMensagem(mensagem). ما دو کلاس داریم که آن را پیاده سازی می کنند: NotificacaoSMS ه NotificacaoEmail. اگرچه این رابط شبیه به وراثت است، جایی که ما یک کلاس انتزاعی را گسترش می‌دهیم، تنها بر تعریف روش‌ها/رفتارها تمرکز می‌کند و از ایجاد قوانین تجاری اجتناب می‌کند. این امر تمام کلاس‌هایی را که آن را پیاده‌سازی می‌کنند مجبور می‌کند تا پیاده‌سازی‌های خود را از این روش‌ها ارائه کنند و به هر یک از آنها اجازه می‌دهد قوانین تجاری خاص خود را ایجاد کنند.

مثال زیر:

public interface Notificacao {
void enviarMensagem(String mensagem);
}

public class NotificacaoEmail implements Notificacao {

// compormanento “forçado” pela interface
@Override
public void enviarMensagem(String mensagem) {
System.out.println(“E-mail: ” + mensagem);
}
}

public class NotificacaoSMS implements Notificacao {

// compormanento “forçado” pela interface
@Override
public void enviarMensagem(String mensagem) {
System.out.println(“SMS: ” + mensagem);
}
}

public class Main {
public static void main(String[] args) {
Notificacao notificacaoEmail = new NotificacaoEmail();
Notificacao notificacaoSMS = new NotificacaoSMS();

notificacaoEmail.enviarMensagem(“Olá, esta é uma notificação via e-mail!”);
notificacaoSMS.enviarMensagem(“Olá, esta é uma notificação via SMS”);
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همانطور که در مثال بالا اشاره شد، هر دو کلاس باید اعلان هایی را برای کاربر ارسال کنند. ما می‌توانیم همه را مجبور کنیم که این عملکرد را پیاده‌سازی کنند، از تکرار کد جلوگیری کرده و استفاده مجدد از مؤلفه‌های ایجاد شده را ترویج کنیم. در قسمت Main می‌توانیم دو کلاس را ببینیم که طبق روش‌های ارسال خاص خود پیام ارسال می‌کنند.

نتیجه گیری

برنامه نویسی شی گرا یک رویکرد قدرتمند برای سازماندهی کد شما به وضوح و کارآمد است. با مفاهیمی مانند encapsulation، inheritance و polymorphism، اکنون وقتی می شنوید که یک زبان بر اساس OOP توسعه یافته یا پشتیبانی می کند، می توانید تصور کنید که چه نوع منابعی را ارائه می دهد.

پیوندهای کمکی

توضیح چکیدهتوضیح رابط

ماهیت OOP ایجاد مدل هایی از اشیاء دنیای واقعی در نرم افزار است. اشیاء می توانند چیزهای ملموسی باشند، مانند ماشین، یا انتزاعی تر، مانند تراکنش بانکی. هر شی دارای حالات و رفتارهایی است. حالت ها ویژگی هایی هستند که شی را تعریف می کنند، در حالی که رفتارها اعمالی هستند که می تواند انجام دهد.

به عنوان مثال، کلاس خودرو را تصور کنید. یک خودرو دارای ویژگی هایی است که ویژگی های آن را توصیف می کند، مانند:

  • رنگ (حالت)،
  • نام تجاری (ایالت)،
  • مدل (حالت)،
  • تعداد پورت ها (حالت).

علاوه بر این، یک ماشین همچنین می تواند اقداماتی مانند:

  1. تماس (رفتار)
  2. راه رفتن (رفتار)
  3. توقف (رفتار).

نمونه کلاس

در اینجا کلاس Car تعریف می کند که هر خودرو (شیء) چه چیزی باید داشته باشد و چه کاری می تواند انجام دهد. ما می‌توانیم هر تعداد خودرو که بخواهیم از این کلاس بسازیم که هر کدام ویژگی‌ها و رفتارهای خاص خود را دارند، اما همیشه از «طرح‌بندی» تعریف‌شده توسط کلاس پیروی می‌کنند.

نمونه ای از نحوه ایجاد این در جاوا به شرح زیر است:

public class Carro {

    String marca;
    String modelo;
    String cor;
    int quantidade_de_portas;

    // inicializamos a classe Carro sem nenhum valor inicial
    public Carro(Strin) {
    }
}

public static void main(String[] args) {
        Carro carro_exemplo = new Carro("Volkswagen ", "Gol", "prata", 4);
        Carro carro_exemplo2 = new Carro("Fiat", "Uno", "prata", 2);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کپسولاسیون

کپسوله‌سازی در جاوا یکی از ارکان برنامه‌نویسی شی گرا (OOP) است و به عمل محدود کردن دسترسی مستقیم به ویژگی‌های یک کلاس اشاره دارد و واضح‌تر می‌کند که کدام قسمت‌های یک شی می‌تواند مستقیماً به آن دسترسی یا تغییر دهد. با آن می توانیم استفاده و دستکاری داده ها را کنترل کنیم و امنیت و یکپارچگی بیشتری را تضمین کنیم.

در جاوا کپسوله سازی از طریق اصلاح کننده های دسترسی مانند privateه publicو با استفاده از متدهای خاص، معروف به getters و setter، که امکان دسترسی یا تغییر ویژگی های یک کلاس را به صورت کنترل شده فراهم می کند.

در مثال زیر:

نمونه کپسولاسیون

کلاس ContaBancaria شامل دو ویژگی Holder و balance است. همانطور که هر دو با اصلاح کننده اعلام می شوند public، آنها را می توان مستقیماً از هر بخشی از سیستم، بدون هیچ گونه کنترل یا اعتبارسنجی، به آنها دسترسی داشت و تغییر داد. این می تواند خطرناک باشد زیرا داده های حساس را می توان در زمان های نامناسب یا نادرست تغییر داد.

اکنون، با استفاده از کپسوله سازی، می توانیم از این داده ها محافظت کنیم:

public class ContaBancaria {
    private String titular;
    private double saldo;

    // Getter
    public String getTitular() {
        return titular;
    }

    public double getSaldo() {
        return saldo;
    }

    // Setter
    public void setTitular(String titular) {
        this.titular = titular;
    }

    public void setSaldo(double saldo) {
        this.saldo = saldo;
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، ویژگی های نگهدارنده و تعادل به اصلاح شد private، به این معنی که نمی توان مستقیماً از خارج از کلاس ContaBancaria به آنها دسترسی داشت. در عوض، ما روش هایی را ایجاد می کنیم دریافت کنید ه مجموعه برای هر یک از این ویژگی ها، که اجازه دسترسی کنترل شده را می دهد. به عنوان مثال، این امر از تغییر مستقیم تعادل توسط هر بخشی از سیستم بدون گذر از قوانین تجاری یا اعتبار سنجی جلوگیری می کند.

مهم است که تأکید کنیم هر زمان که ما نیاز به کنترل نحوه ارائه داده برای کسانی که از خارج به مقداری از این کلاس دسترسی دارند، از دریافت کننده استفاده می شود. به همین ترتیب، تنظیم کننده برای پیاده سازی تغییرات به روشی ایمن تر و محدودتر در ویژگی ها ایجاد می شود و اجازه می دهد تا قوانین یا اعتبارسنجی ها قبل از تغییر مقادیر اعمال شوند.

اکنون، برای دسترسی یا اصلاح ویژگی های ContaBancaria، کد باید متدهای مناسب را فراخوانی کند:

ContaBancaria conta = new ContaBancaria();
conta.setTitular("Felipe");
conta.setSaldo(0.0);

System.out.println(conta.getTitular());

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این کار، ما تضمین می کنیم که تنها راه تغییر نگهدارنده یا بالانس از طریق روش های خاصی است که سیستم را در برابر تغییرات یا خطاهای ناخواسته محافظت می کند، مانند:

conta.titular = "Bruno";
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

میراث

وراثت یکی از ارکان اساسی برنامه نویسی شی گرا (OOP) است. مفهوم وراثت به یک کلاس (به نام زیر کلاس) اجازه می دهد تا ویژگی ها و رفتارها را از کلاس دیگر (به نام سوپرکلاس) به ارث ببرد. با وراثت، امکان استفاده مجدد و تخصصی کردن کد موجود وجود دارد که توسعه سیستم ها را کارآمدتر و سازماندهی می کند.

وراثت چگونه مفید است؟

تصور کنید کلاسی به نام Card دارید که دارای ویژگی ها و رفتارهای مشترک در انواع مختلف کارت ها مانند کارت های بدهی و اعتباری است. به جای تکرار این ویژگی ها و رفتارها در هر نوع کارت، می توانید آنها را در کلاس Card متمرکز کنید و سپس این ویژگی ها را در زیر کلاس ها به ارث ببرید. CartaoDebito ه CartaoCredito.

مثال زیر:

مثال ارث

در نمودار بالا، کلاس Cartao دارای سه ویژگی مشترک است: codigo_cartao، numero_cartao ه digito_cartao. این ویژگی ها به عنوان علامت گذاری شده اند protected، که به این معنی است که می توان آنها را مستقیماً توسط زیر کلاس ها در دسترس قرار داد و تغییر داد، اما توسط سایر کلاس های خارجی نمی توان آنها را تغییر داد.

حالا دو زیر کلاس داریم:

  • کارت بدهی: ویژگی های کلاس را به ارث می برد Cartao و رفتارها و صفات خاصی مانند data_pagamento_deposito ه data_saqueو همچنین روش های برداشت و واریز پول.
  • کارت اعتباری: همچنین ویژگی های Cartao را به ارث می برد، اما ویژگی های خاصی را اضافه می کند، مانند se_pode_aproximacao و رفتارهای پرداخت با/بدون تماس و بررسی محدودیت کارت.

در این مثال، کلاس ها CartaoDebito ه CartaoCredito ویژگی ها و متدها را از کلاس به ارث می برند Cartao. به این ترتیب، ما از کد پایه سوپرکلاس استفاده مجدد می کنیم، که نگهداری و توسعه را ساده می کند. علاوه بر این، هر زیر کلاس می‌تواند نسخه‌های روش‌های خاص خود را پیاده‌سازی کند یا رفتارهای جدید خاصی را اضافه کند و انعطاف‌پذیری و تخصص مورد نیاز برای هر نوع کارت را تضمین کند.

مثال زیر:

public abstract class Cartao {
    protected String codigo_cartao;
    protected String numero_cartao;
    protected String digito_cartao;

    // Métodos comuns
    public abstract void sacarDinheiro(double valor);
    public abstract void depositarDinheiro(double valor);
}

// Subclasse Cartão de Débito
public class CartaoDebito extends Cartao {
    private String data_deposito;
    private String data_saque;

    @Override
    public void sacarDinheiro(double valor) {
        System.out.println("Sacando dinheiro do Cartão de Débito");
        // Lógica específica para o saque
        // Adicionar data de saque;
    }

    @Override
    public void depositarDinheiro(double valor) {
        System.out.println("Depositando dinheiro no Cartão de Débito");
        // Lógica específica para o depósito
        // Adicionar data de deposito;
    }
}

// Subclasse Cartão de Crédito
public class CartaoCredito extends Cartao {
    private String data_pagamento;
    private boolean se_pode_aproximacao;

    @Override
    public void sacarDinheiro(double valor) {
        System.out.println("Sacando dinheiro do Cartão de Crédito");
        // Lógica específica para o saque
    }

    @Override
    public void depositarDinheiro(double valor) {
        System.out.println("Depositando dinheiro no Cartão de Crédito");
        // Lógica específica para o depósito
    }

    public void pagar() {
        if (se_pode_aproximacao) {
            System.out.println("Pagamento com aproximação");
        } else {
            System.out.println("Pagamento sem aproximação");
        }
        // Adiciona data de pagamento;
    }

    public void verificarSeTemLimite() {
        // Lógica para verificar o limite do cartão
        System.out.println("Verificando limite do Cartão de Crédito");
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، کلاس ها CartaoDebito ه CartaoCredito ویژگی ها و متدها را از کلاس Cartao به ارث می برند. به این ترتیب، ما از کد پایه سوپرکلاس استفاده مجدد می کنیم، که نگهداری و توسعه را ساده می کند. علاوه بر این، هر زیر کلاس می‌تواند نسخه‌های روش‌های خاص خود را پیاده‌سازی کند یا رفتارهای جدید خاصی را اضافه کند و انعطاف‌پذیری و تخصص مورد نیاز برای هر نوع کارت را تضمین کند.

چند شکلی

اکنون که وراثت را درک کردیم، بیایید در مورد چیزی صحبت کنیم که بسیار به آن مرتبط است، یعنی چند شکلی به عبارت ساده به معنای “شکل های متعدد” است – یعنی توانایی یک شی برای به خود گرفتن اشکال مختلف. در زمینه OOP، پلی مورفیسم به همان عمل (مانند استفاده از یک رویه) اجازه می دهد تا بسته به شیئی که آن را انجام می دهد، به روش های مختلف رفتار کند.

این بسیار مفید است زیرا به ما امکان می دهد با اشیاء مختلف به طور یکنواخت رفتار کنیم، اما همچنان به هر شی اجازه می دهد تا رفتار خاص خود را داشته باشد.

در مثالی که قبلا دیدیم، یک کلاس پایه به نام Cartao داریم که توسط دو کلاس گسترش می‌یابد: CartaoDebito ه CartaoCredito. هر یک از این زیر کلاس ها رفتارهای مخصوص به نوع کارت را پیاده سازی می کنند، مانند sacarDinheiro() ه depositarDinheiro().

حال، بیایید ببینیم چگونه می توان از چندشکلی برای رفتار با انواع مختلف کارت ها به روشی یکنواخت استفاده کرد، اما به هر کارت اجازه می دهد تا مطابق با ویژگی های خود عمل کند.

public class Main {
    public static void processarSaque(Cartao cartao, double valor) {
        cartao.sacarDinheiro(valor);
    }

    public static void processarDeposito(Cartao cartao, double valor) {
        cartao.depositarDinheiro(valor);
    }

    public static void main(String[] args) {
        Cartao cartaoDebito = new CartaoDebito();
        Cartao cartaoCredito = new CartaoCredito();

        // Polimorfismo em ação: o método sacarDinheiro se comporta de maneira diferente para cada tipo de cartão
        processarSaque(cartaoDebito, 100);  // Comportamento específico do Cartão de Débito
        processarSaque(cartaoCredito, 200); // Comportamento específico do Cartão de Crédito

        processarDeposito(cartaoDebito, 500);  // Depósito no Cartão de Débito
        processarDeposito(cartaoCredito, 1000); // Depósito no Cartão de Crédito
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در کد بالا دو متد به نام داریم processarSaque ه processarDeposito. این متدها یک شی از نوع دریافت می کنند Cartao به عنوان یک آرگومان، به این معنی که آنها می توانند هر زیر کلاسی را بپذیرند Cartao، مانند CartaoDebito یا CartaoCredito.

رفتار چند شکلی زمانی اتفاق می افتد که متد را فراخوانی کنیم sacarDinheiro() ه depositarDinheiro() در انواع مختلف کارت حتی اگر روش ها به یک شکل نامیده می شوند، رفتار بر اساس نوع شی تغییر می کند (خواه a CartaoDebito یا الف CartaoCredito). این چند شکلی در عمل است – روش بسته به شیئی که آن را فراخوانی می کند متفاوت رفتار می کند.

چند شکلی کد را انعطاف پذیرتر و مقیاس پذیرتر می کند. توجه داشته باشید که در مثال، روش‌هایprocessWithdraw andprocessDeposito برای مقابله با انواع مختلف کارت‌ها نیازی به تغییر یا تکرار ندارند. آنها هر شیئی را که نمونه ای از کلاس باشد می پذیرند Cartao، و رفتار مناسب است به صورت پویا تصمیم گرفت، بر اساس نوع کارت خاص.

رابط

رابط، آخرین اما نه کم اهمیت ترین، یکی از ارکان برنامه نویسی شی گرا (OOP) است و به طور گسترده مورد استفاده قرار می گیرد. این اثر معکوس وراثت دارد: در حالی که وراثت به کلاس فرزند اجازه می دهد تا ویژگی های کلاس والد را به ارث ببرد، رابط تمام کلاس هایی را که آن را پیاده سازی می کنند مجبور می کند تا منطق خود را برای متدهای تعریف شده ارائه کنند. این تضمین می‌کند که هر کلاس با یک قرارداد خاص مطابقت دارد، و ثبات و استفاده مجدد از کد را ارتقا می‌دهد.

مثال زیر:

رابط مثال

در این مثال، ما رابطی به نام داریم Notificacao، که متدی به نام دارد enviarMensagem(mensagem). ما دو کلاس داریم که آن را پیاده سازی می کنند: NotificacaoSMS ه NotificacaoEmail. اگرچه این رابط شبیه به وراثت است، جایی که ما یک کلاس انتزاعی را گسترش می‌دهیم، تنها بر تعریف روش‌ها/رفتارها تمرکز می‌کند و از ایجاد قوانین تجاری اجتناب می‌کند. این امر تمام کلاس‌هایی را که آن را پیاده‌سازی می‌کنند مجبور می‌کند تا پیاده‌سازی‌های خود را از این روش‌ها ارائه کنند و به هر یک از آنها اجازه می‌دهد قوانین تجاری خاص خود را ایجاد کنند.

مثال زیر:

public interface Notificacao {
    void enviarMensagem(String mensagem);
}

public class NotificacaoEmail implements Notificacao {

    // compormanento "forçado" pela interface
    @Override
    public void enviarMensagem(String mensagem) {
        System.out.println("E-mail: " + mensagem);
    }
}


public class NotificacaoSMS implements Notificacao {

    // compormanento "forçado" pela interface
    @Override
    public void enviarMensagem(String mensagem) {
        System.out.println("SMS: " + mensagem);
    }
}


public class Main {
    public static void main(String[] args) {
        Notificacao notificacaoEmail = new NotificacaoEmail();
        Notificacao notificacaoSMS = new NotificacaoSMS();

        notificacaoEmail.enviarMensagem("Olá, esta é uma notificação via e-mail!");
        notificacaoSMS.enviarMensagem("Olá, esta é uma notificação via SMS");
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همانطور که در مثال بالا اشاره شد، هر دو کلاس باید اعلان هایی را برای کاربر ارسال کنند. ما می‌توانیم همه را مجبور کنیم که این عملکرد را پیاده‌سازی کنند، از تکرار کد جلوگیری کرده و استفاده مجدد از مؤلفه‌های ایجاد شده را ترویج کنیم. در قسمت Main می‌توانیم دو کلاس را ببینیم که طبق روش‌های ارسال خاص خود پیام ارسال می‌کنند.

نتیجه گیری

برنامه نویسی شی گرا یک رویکرد قدرتمند برای سازماندهی کد شما به وضوح و کارآمد است. با مفاهیمی مانند encapsulation، inheritance و polymorphism، اکنون وقتی می شنوید که یک زبان بر اساس OOP توسعه یافته یا پشتیبانی می کند، می توانید تصور کنید که چه نوع منابعی را ارائه می دهد.

پیوندهای کمکی

توضیح چکیده
توضیح رابط

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا