Skip to main content

Class Names Should Not Shadow Interfaces or Superclasses

Medium
maintainabilityintentionality - clear

What is it?

This practice addresses the issue of class name shadowing, where a class name is identical to that of its superclass or an interface it implements.

Why apply it?

Class name shadowing leads to ambiguity, making it unclear which class is being referred to, which can result in potential bugs and reduced code readability.

How to fix it?

Rename the class to use a more descriptive and unique name that doesn’t conflict with its superclass or implemented interfaces names.

Examples

Example 1:

Negative

The negative example shows a class shadowing the interface it implements, causing ambiguity and potential bugs.

package org.foo.domain;

public interface User {
void login();
}

package org.foo.presentation;

public class User implements org.foo.domain.User { // Noncompliant
public void login() {
System.out.println("Logging in...");
}
}

Example 2:

Positive

The positive example uses unique and descriptive class names that do not conflict with superclasses or implemented interfaces.

package org.foo.domain;

public interface User {
void login();
}

package org.foo.presentation;

import org.foo.domain.User;

public class UserView implements User { // Compliant
public void login() {
System.out.println("Logging in...");
}
}

Negative

In this negative example, the class name shadows its superclass, leading to confusion.

package org.foo.domain;

public class BaseEntity {
private int id;

public int getId() {
return id;
}
}

package org.foo.data;

public class BaseEntity extends org.foo.domain.BaseEntity { // Noncompliant
private String recordData;

public String getRecordData() {
return recordData;
}
}

Example 3:

Positive

This positive example demonstrates a class uniquely named, avoiding conflicts with the superclass.

package org.foo.domain;

public class BaseEntity {
private int id;

public int getId() {
return id;
}
}

package org.foo.data;

import org.foo.domain.BaseEntity;

public class EntityRecord extends BaseEntity { // Compliant
private String recordData;

public String getRecordData() {
return recordData;
}
}